猿问

使用 socket.io 事件更新状态

我有一个反应功能组件:


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 状态更新


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


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


鸿蒙传说
浏览 181回答 2
2回答

富国沪深

您需要在 useEffect 函数中设置套接字侦听器,否则在每次重新渲染时都会创建一个新实例,而旧实例将继续侦听并导致内存溢出和意外的状态更新错误。还要清除您的套接字侦听器function Chat(props) {&nbsp; const [messages, setMessages] = useState([]);&nbsp; const inputRef = useRef();&nbsp; useEffect(() => {&nbsp; &nbsp; &nbsp; //The socket is a module that exports the actual socket.io socket&nbsp; &nbsp; &nbsp; const addMessage = (msg) => setMessages(prevMessages => [...prevMessages, msg]);&nbsp; &nbsp; &nbsp; socket.socket.on("chatMessage", addMessage)&nbsp; &nbsp; &nbsp; () => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // turning of socket listner on unmount&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; socket.off('chatMessage', addMessage);&nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; }, [])&nbsp; const inputChanged = (e) => {&nbsp; &nbsp; if (e.key === "Enter") {&nbsp; &nbsp; &nbsp; socket.sendMessage(inputRef.current.value)&nbsp; &nbsp; &nbsp; &nbsp; .then(() => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //do something&nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; .catch(console.log);&nbsp; &nbsp; &nbsp; inputRef.current.value = "";&nbsp; &nbsp; }&nbsp; };&nbsp; return (&nbsp; &nbsp; &nbsp; <div>&nbsp; &nbsp; &nbsp; &nbsp; {messages.map((msg, i) => <ChatMessage key={i}>{msg}</ChatMessage>)}&nbsp; &nbsp; &nbsp; &nbsp; <input ref={inputRef} onKeyPress={inputChanged} />&nbsp; &nbsp; &nbsp;</div>&nbsp; );}// PS 确保你使用回调方法来更新状态

梵蒂冈之花

套接字是副作用。useEffecf(() => {&nbsp; const callback =&nbsp; (msg) => {&nbsp; &nbsp; setMessages([...messages, msg]);&nbsp; };&nbsp; socket.socket.on("chatMessage", callback);&nbsp; return () => {&nbsp; &nbsp; socket.socket.off("chatMessage", callback);&nbsp; };}, []);
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答