javascript - 使用 socket.io 事件更新状态

标签 javascript reactjs socket.io react-functional-component

我有一个 react 功能组件:

function Chat(props) {
  const [messages, setMessages] = useState([]);

  const inputRef = useRef();

  //The socket is a module that exports the actual socket.io socket
  socket.socket.on("chatMessage", (msg) => {
    setMessages([...messages, msg]);
  });

  const inputChanged = (e) => {
    if (e.key === "Enter") {
      socket.sendMessage(inputRef.current.value)
        .then(() => {
          //do something
        })
        .catch(console.log);
      inputRef.current.value = "";
    }
  };

  return (
      <div>
        {messages.map((msg, i) => <ChatMessage key={i}>{msg}</ChatMessage>)}
        <input ref={inputRef} onKeyPress={inputChanged} />
     </div>
  );
}

但是当我从 socket.socket.on("chatMessage" 更新状态时,我得到一个错误

Can't perform a React state update on an unmounted component

并且套接字告诉我响应需要很长时间,并且开始发生一些递归。

我应该如何从套接字事件更新我的组件状态?

最佳答案

您需要在 useEffect 函数中设置套接字监听器,否则在每次重新渲染时都会创建一个新实例,而旧实例将继续监听并导致内存溢出和意外的状态更新错误。还要清除你的套接字监听器

function Chat(props) {
  const [messages, setMessages] = useState([]);

  const inputRef = useRef();

  useEffect(() => {
      //The socket is a module that exports the actual socket.io socket
      const addMessage = (msg) => setMessages(prevMessages => [...prevMessages, msg]);
      socket.socket.on("chatMessage", addMessage)
      () => {
            // turning of socket listner on unmount
          socket.off('chatMessage', addMessage);
       }
  }, [])

  const inputChanged = (e) => {
    if (e.key === "Enter") {
      socket.sendMessage(inputRef.current.value)
        .then(() => {
          //do something
        })
        .catch(console.log);
      inputRef.current.value = "";
    }
  };

  return (
      <div>
        {messages.map((msg, i) => <ChatMessage key={i}>{msg}</ChatMessage>)}
        <input ref={inputRef} onKeyPress={inputChanged} />
     </div>
  );
}

//附言确保您正在使用回调方法来更新状态

关于javascript - 使用 socket.io 事件更新状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61042360/

相关文章:

node.js - 在其他JS文件中使用socket.io模块

javascript - Mousemove 不在服务器上循环 - 但在 jsbin 中工作

arrays - React Redux 将数组放入存储中,仅在第一次更改时更新

reactjs - 取消订阅 rxjs 中的计时器

javascript - 连接时从客户端发出 socket.io 消息

matlab - 使用 Socket.io 和 Matlab

javascript - 如果用户多次单击元素,如何避免竞争条件?

javascript - 如何删除babel添加的全局 "use strict"

javascript - if IE >= 9 或 not IE 的条件指令

reactjs - Material-ui withTheme() 给出错误 "TypeError: Object(...) is not a function"