组件恢复状态



export const Component = () => {
    const [messages, setMessages] = useState([]);
    const sendMessage = msg => {
        socket.emit('message', msg);
        setMessages([
            ...messages,
            {
                content: msg.content
            }
        ])
    };
    const onMessage = msg => setMessages([
        ...messages,
        {
            content: msg.content
        }
    ]);
    useEffect(() => {
        socket.on('message', onMessage)
    }, []);
    return (
        <button onClick={() => sendMessage({content: 'test'})}/>
    )
};

这是我如何实现发送/获取消息的示例代码。问题在于,如果我从套接字(Onmessage(收到消息,始终会恢复消息。一切都很好,如果我通过sendMessage函数进行操作,则消息正在填充。

谢谢!

编辑:我已经解决了这个问题,有答案:

 useEffect(() => {
        socket.on('message', onMessage)
    }, [messages]); //rerender if messages changed

,但我不明白为什么这能解决我的问题。有人可以解释吗?

编辑2:

 useEffect(() => {
        socket.on('message', onMessage)
        return () => {
          socket.off('message', onMessage);
        }
    }, [messages]); //rerender if messages changed

您如何看待此解决方案?

您的问题是closure的简单情况。当您在初始加载期间将事件侦听器方法设置为套接字时,onMessage甚至使用其词汇范围。但是,在接下来的下一篇后续渲染过程中,创建了一个新的Onmessage,其更新的词汇范围并未将其重新分配给socket event,因此它引用了最初加载期间存在的messages值。

但是,如果您写下效果以执行每个消息更改,则在消息更改重新渲染上创建的新的Onmessage方法正在分配给套接字事件,并且可以正常工作。

但是,比使用messages作为useEffect中的依赖性更好的解决方案是使用状态更新回调

const onMessage = msg => setMessages(prevMessages => ([
    ...prevMessages,
    {
        content: msg.content
    }
]));
useEffect(() => {
    socket.on('message', onMessage)
    return () => {
      socket.off('message', onMessage);
    }
}, []);

相关内容

  • 没有找到相关文章

最新更新