React useState,useEffect 中的 setState 不更新数组

gra*_*son 3 reactjs react-hooks use-effect

我在 SO 上看到过这个问题,但我似乎无法弄清楚它为什么存在。

我从这里开始学习教程

我正在使用 useState 但当我尝试更新状态时,数组为空。我正在使用状态最初创建一个空数组。在收到消息时,我尝试使用扩展运算符将消息添加到数组中,我已经无数次使用它来将对象添加到数组中(但从未在 useEffect 中使用)。

如果我取消注释行的注释,“聊天”将按其应有的方式更新,但我无法理解为什么扩展运算符不起作用,我需要使用 useRef 来使其工作。我不想为每个相应的 useState 提供大量的 useRef (至少不知道为什么有必要)

任何人都可以看到我做错了什么,或者解释为什么我需要 useRef 吗?

const [chat, setChat ] = useState([]);

//const latestChat = useRef(null);
//latestChat.current = chat;

// ...

useEffect(() => {
    if (connection) {
        connection.start()
            .then(result => {
                console.log('Connected!');

                connection.on('ReceiveMessage', message => {
                    const newMsg = {
                        user: message.user,
                        message:message.message
                    }
                    setChat([...chat, newMsg]); // issue with this line. chat is always empty

                    //const updatedChat = [...latestChat.current];
                    //updatedChat.push(message);
                    //setChat(updatedChat);
                    
                    
                });
            })
            .catch(e => console.log('Connection failed: ', e));
    }
}, [connection]);
Run Code Online (Sandbox Code Playgroud)

Tag*_*ari 7

你这里有两个选择

  1. 添加chat状态,useEffect dependency array以便它知道它取决于chat.
useEffect(() => {
  if (connection) {
    //...
    setChat([...chat, newMsg]); // issue with this line. chat is always empty
    //...
  }
}, [connection, chat]);
Run Code Online (Sandbox Code Playgroud)
  1. 用于setState callback更新,chat这样你就不会得到stale data
useEffect(() => {
  if (connection) {
    //...
    setChat((ch) => [...ch, newMsg]); // issue with this line. chat is always empty
    //...
  }
}, [connection]);
Run Code Online (Sandbox Code Playgroud)

其中第二种方式更合适。