【问题标题】:UseState in useEffect hook with empty array (for socket.io.on)空数组的 useEffect 钩子中的 UseState(用于 socket.io.on)
【发布时间】:2021-12-14 09:24:55
【问题描述】:

目前我有以下代码:

export default function Chat() {
    const [chat, setChat] = useState({ ID: 0, messages: [] })
    const {socket} = useContext(SocketContext)

    useEffect(() => {
        socket.on('/chat', (message) => {
            setChat({...chat, messages: [...chat.messages, message] }
            //Some other interaction with variables inside this Chat function (eg: document.getElementById)
        }
    }, [])
 
    return <div>{chat.toDivs()}</div>
}

但这并没有按预期工作,因为 useEffect 总是使用相同的 chat 值。因此,在 /chat 上接收消息的结果将始终是 [message] 而不是 [...prevMessages, message]。

我搜索过这个问题,有人建议使用 componentDidMount(),但是由于我没有使用 React.Component 可扩展类,所以我不能使用该方法。

有什么好的,简单的解决方案吗?

【问题讨论】:

    标签: socket.io react-hooks


    【解决方案1】:

    使用功能状态更新,以便您从之前的状态进行更新而不是在回调范围内关闭的状态值。

    卸载时不要忘记取消订阅以清理资源。

    const [chat, setChat] = useState({ ID: 0, messages: [] });
    
    useEffect(() => {
      const onChat = (message) => {
        setChat(chat => ({
          ...chat,
          messages: [...chat.messages, message],
        }));
      };
    
      socket.on('/chat', onChat);
    
      return () => socket.off('/chat', onChat);
    }, []);
    

    【讨论】:

    • 将消息作为对象如何工作。如果我这样做 setChat(chat => {...chat, messages: [...chat.messages, message]}),它就不起作用。可能我在这里犯了一个小错误
    • @UltraDonut 你是在问chat 是否是一个带有messages 数组的对象吗?
    • 是的,聊天对象也有一些信息,例如 ID
    • @UltraDonut 我明白了。您能否更新您的问题以包含 actual chat 状态形状,因为它似乎不仅仅是一个数组?
    • 当然,我已经更新了。谢谢你花时间帮助我顺便说一句:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-02
    • 2020-06-22
    • 2023-03-19
    • 1970-01-01
    • 2021-12-01
    • 2021-04-04
    • 1970-01-01
    相关资源
    最近更新 更多