javascript - socket.io 监听器在函数式 React 中触发太多次

标签 javascript reactjs sockets react-hooks

我正在使用 create-react-app、react hooks 构建在线棋盘游戏,并使用 sockets.io 在连接的用户之间传输数据(玩家位置、活跃玩家等)。逻辑流程是用户做出选择,该选择被添加到状态数组中,然后更新的状态通过套接字推送到所有连接的用户。问题在于,负责从后端接收套接字数据并更新每个连接用户的用户数据的 useEffect 监听器触发了太多次,而不是一次。

代码:

向后端发送调用:

try {
          console.log(currentCard, typeof(currentCard.title), tech)
          setUser1Data({
            ...user1Data,
             userTech: [...user1Data.userTech, currentCard.title]
          });
        } finally {
          console.log(user1Data)
            socket.emit("p1state", user1Data);
           pass();
        }

后端接收器/发射器:

socket.on("p1state", function(state) {
    console.log(state)
    io.emit("p1state", state)
  })

客户端监听器:

  useEffect(() => {
    socket.on("p1state", state => {
      console.log("1")
      setUser1Data({...user1Data, state});
    });
  }, [user1Data]);

我注意到一些“有趣”的事情:这个 useEffect 被触发了太多次。第一次触发时,它会按照应有的方式设置所有内容,但随后每次它都会覆盖以前的设置,恢复到原始的 user1Data 状态对象。

此外,在后端,当客户端连接时,我会触发 console.log 。尽管我目前仅使用一个浏览器选项卡进行本地测试,但它仍在记录多个用户连接的事件。

最佳答案

useEffect 当前正在使用依赖项数组中的状态,并在更新程序函数中设置相同的状态。正如您所看到的,这会导致无限循环。

useEffect(() => {
    socket.on("p1state", state => {
      console.log("1")
      setUser1Data(userData => ({...userData, state}));
    });
}, []);

相反,您可以使用状态 setter 的函数版本,以便它为您提供准确的 prevState 而不是依赖于闭包中的状态表示。

关于javascript - socket.io 监听器在函数式 React 中触发太多次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60658254/

相关文章:

javascript - 为什么单击按钮时对象不移动?

javascript - 我在 IE8 中不断收到 Object.create 错误

javascript - 如何使用 Javascript 更改 div 位置?

html - 子组件无法正确渲染

javascript - 如何中止一批异步获取请求?

c++ - UDP NAT穿越

python - IRC 机器人使循环休眠而不中断主循环

c# - 下一个排队数据报的大小 - UDP

javascript - 使用 Tab 从一个 contenteditable 切换到下一个

Reactjs 输入值没有改变