React Hooks:在 Socket.io 处理程序中调用时状态不会更新

IT技术 node.js reactjs socket.io react-hooks
2021-05-02 05:52:03
const [questionIndex, setQuestionIndex] = useState(0);

...

socket.on('next', () => {
      console.log('hey')
      setQuestionIndex(questionIndex + 1);
});

...


useEffect(() => {
    console.log(questionIndex);
}, [questionIndex]);

我有一个使用 Socket.io 连接到 websocket 的页面。当我从套接字收到“下一个”消息时,我试图更新我的 questionIndex 状态变量的值。我似乎收到了消息,因为打印了“嘿”,但 questionIndex 仅在第一个“嘿”之后更新。之后,嘿被打印,但 questionIndex 不是(我使用 useEffect 在更新时打印 questionIndex)。大家有没有看出哪里不对劲?

3个回答

我也面临这个问题。实际上,我们不应该在更新时依赖状态的值。

正确的做法是

setQuestionIndex(QuestionIndex=>QuestioIndex+1)

对于那些想知道的人,看起来 socket.on('next') 函数处理程序每​​次都使用 questionIndex 的原始值(0)。看起来函数处理程序在绑定时编译了这个变量,而不是在运行时读取它。不确定它在文档中的哪个位置指定了这种行为。

我的解决方案是这样更改函数处理程序:

socket.on('next', (newIndex) => {
      console.log('hey')
      setQuestionIndex(newIndex);
});

这通过提供将 questionIndex 设置为的值来解决问题(而不是在收到“下一个”事件时读取它)。

看起来你每次渲染都打开新的套接字并且永远不会断开它。尝试将 socket.on 放在 useEffect 中,该 useEffect 的返回值将是断开套接字的函数。

useEffect(() => {
  socket.on('next', () => {
    console.log('hey')
    setQuestionIndex(questionIndex + 1);
  });

  return () => socket.disconnect();
}, [questionIndex]);```