使用 React 处理 Websocket 数据

问题描述 投票:0回答:1

我正在使用React和websocket编写一个实时应用程序,有一个问题,我从websocket获取数据,这里没有问题,但是当它滚动时,我编写了以下代码来获取更多代码,它起作用了,但是这次它一遍又一遍地渲染相同的数据,即使数据库中有 10 个数据。这是什么原因呢? ( [. ..prevPost,...prev] 结构,我在字符串中组合新数据和旧数据,如果删除它,问题仍然相同,如果我删除它,我的意思是只给出 post 变量,这次它没有添加旧数据并完全渲染页面。我使用 dotnet websocket signalr 编写我的背景。

import React, { useEffect, useState, useRef } from "react";
import { PostLayout } from "../Components/PostLayout";
import { Post } from "../Components/Post";
import { Loading } from "../Components/Loading";
import { HubConnectionBuilder, HttpTransportType } from "@microsoft/signalr";

export const Home = () => {
  const [post, setPost] = useState([]);
  const page = useRef(0);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const connection = new HubConnectionBuilder()
      .withUrl("http://localhost:5226/posts", {
        transport: HttpTransportType.WebSockets,
      })
      .build();
    const loader = () => {
      connection.on("ReceivePosts", (post) => {
        setPost((prevPosts) => [...prevPosts, ...post]);
        setLoading(false);
      });

      connection.on("SendPost", (post) => {
        setPost((prev) => [...prev, ...post]);
        setLoading(false);
      });

      connection
        .start()
        .then(() => {
          connection.invoke("GetPosts", page.current, 5).then((res) => {
            console.log(res);
          });
        })
        .catch((err) => console.log("Error: ", err.toString()));
    };
    loader();
    const handleScroll = () => {
      if (window.innerHeight + window.scrollY >= document.body.offsetHeight && !loading) {
          page.current += 1;
          connection.invoke("GetPosts", page.current, 3)
              .then((res) => {
                  console.log(res);
                  setLoading(false);
              })
              .catch((err) => {
                  console.log("Error: ", err.toString());
                  setLoading(false);
              });
      }
    };
    window.addEventListener("scroll", handleScroll);
    return () => {
      window.removeEventListener("scroll", handleScroll);
    };
  }, [loading]);

  return (
    <>
      <div className={"grid columns-10 justify-center row-auto gap-8 top-5"}>
        <div className={"w-full "}>
          <PostLayout>
            <div className={"w-full flex flex-col gap-8 "}>
              {loading ? (
                <div className="relative top-32">
                  <Loading />
                </div>
              ) : (
                post.map((prop, index) => {
                  return (
                    <Post
                      key={index}
                      author={prop.author}
                      text={prop.content}
                      url={prop.url}
                      image={prop.image}
                    />
                  );
                })
              )}
            </div>
          </PostLayout>
        </div>
      </div>
    </>
  );
};
reactjs typescript websocket signalr
1个回答
0
投票

我不熟悉

@microsoft/signalr
库,但我的猜测是,滚动会导致调用
GetPosts
并通过
ReceivePosts
收集数据并将其添加到状态的无限循环。

准确地说,您的

handleScroll
函数调用
connection.invoke("GetPosts", page.current, 3)
并且(我假设)您的
connection.on("ReceivePosts")
侦听器将再次从数据库接收相同的帖子,并将它们添加到状态中。

© www.soinside.com 2019 - 2024. All rights reserved.