如何使用钩子将项目追加到React组件中的数组?

时间:2019-08-08 18:12:20

标签: socket.io react-hooks spread-syntax use-effect

我正在尝试使用Socket.io和React(挂钩)建立一个聊天室。我有往返服务器的事件,但是当我尝试在客户端更新messages数组时,该数组会不断替换,而不是更新。

客户(反应)

const socket = io(process.env.REACT_APP_API_URL);
const [currentMessage, setCurrentMessage] = useState(null);
const [messages, setMessages] = useState([]);

function sendMessage(e) {
  e.preventDefault();

  // emit message to server
  socket.emit('add', currentMessage);
}

useEffect(() => {

  // listen for add message event from server
  socket.on('add', function(msg) {
    // add new message to messages array
    setMessages([...messages, msg]);
  });

}, []);

// loop through messages
const items = messages.map((msg, key) =>
  <li key={key}>{msg}</li>
);

return (
  <ul className="chat">
    {items}
  </ul>
  <input type="text" onChange={(e) => setCurrentMessage(e.target.value)}>
  <button type="submit" onClick={(e) => sendMessage(e)} />
);

同样,已成功从服务器接收到消息,但是我的messages数组中仅包含一项-最新消息。我认为使用散布运算符(即setMessages([...messages, msg]))将保留其他数组项。我没看到什么?

1 个答案:

答案 0 :(得分:1)

您的代码等效于setMessages([...[], msg]),因为messages是1个渲染中的常量(请参见const关键字),并且仅在第一个渲染中的useEffect内部运行该函数。是[]

使用functional updates

setMessages((currentMessages) => [...currentMessages, msg])