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

Posted

技术标签:

【中文标题】如何使用钩子将项目附加到 React 组件中的数组?【英文标题】:How can I append an item to an array in a React component using hooks? 【发布时间】:2019-12-16 12:21:15 【问题描述】:

我正在尝试使用 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]))会保留其他数组项。我没看到什么?

【问题讨论】:

您确定要向服务器发送message 吗?我看不到 message 的定义位置。我看到了currentMessagemessages,但没有看到message @MikeHorn 很好。我的错。发射函数中的message 确实应该是currentMessage 【参考方案1】:

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

使用functional updates:

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

【讨论】:

行得通!谢谢你的解释。现在对我来说很有意义。

以上是关于如何使用钩子将项目附加到 React 组件中的数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用钩子将 React 类组件转换为功能组件

如何在我的组件库中使用 React 钩子?

React 生命周期钩子

Reactjs,使用材质UI:无效的钩子调用错误

使用 React 钩子,我如何更新通过道具传递给孩子的对象?

如何将 React 组件的自定义钩子与“map”一起使用