You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React JS 向数组插入新对象时始终替换最后一项而非新增的问题

问题根因

你遇到的是React Hooks的闭包陷阱问题:你的useEffect依赖数组仅填写了props.conversation_id,只会在会话ID变化时重新执行,因此useEffect内部的messageListener函数永远捕获的是首次执行useEffect时的chatList初始值。每次收到新消息执行[...chatList, message]时,用的都是旧的初始列表,自然只会保留初始值+最新一条消息,看起来就像替换了最后一项。

解决方案

最优方案是使用setState的函数式更新语法,直接从状态的最新值计算新状态,不需要依赖外部的chatList变量,修改后代码如下:

const [chatList, setChatList] = useState(props.chatList ? props.chatList : []);

useEffect(() => {
    const messageListener = (message) => {
        console.log('message',message);
        console.log('chatList',chatList);

        if(message.conversation_id == props.conversation_id){
            // 改用函数式更新,直接读取最新的历史列表拼接新消息
            setChatList(prevChatList => [...prevChatList, message]);
        }
        
    };
  
    socket.on('myEventName', messageListener);

    return () => {
      socket.off('myEventName', messageListener);
    };
}, [props.conversation_id]);

如果不想用函数式更新,也可以把chatList加到useEffect的依赖数组中即可生效,但要注意每次依赖变化时都会重新注册监听函数,需要确保卸载逻辑正确移除旧监听,综合更推荐上面的函数式更新写法。

内容的提问来源于stack exchange,提问作者Devsi Odedra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 10:36:07