使用socket.io事件更新状态

时间:2020-04-05 12:10:53

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

我有一个反应功能组件:

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"更新状态时,出现错误

无法在未安装的组件上执行React状态更新

套接字告诉我,它花了很长时间才能响应,并且开始出现一些递归。

如何通过套接字事件更新组件状态?

2 个答案:

答案 0 :(得分:2)

您需要在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>
  );
}

// P.S.确保您使用的是回调方法来更新状态

答案 1 :(得分:0)

套接字是副作用。

const roles = message.member.roles.cache.array();

for (var i = 0; i < roles.length; i++) {
      if (roles[i].name.substring(0, 1) == "*") {
            message.member.roles.remove(roles[i]);
      }

}