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

React点击按钮更新状态无法获取最新值,状态被替换而非追加

React状态数组追加更新失败的解决方法

问题描述

timeline是一个数组状态,用于渲染元素列表。点击按钮时,期望将新内容追加到状态数组中,但实际效果是替换原有内容(比如点击Update按钮后,页面内容从Hi+按钮变成Bye,而非Hi+按钮+Bye)。尝试过用JSON.stringify和JSON.parse深拷贝,但因为数组中包含JSX元素无法序列化,所以该方法无效。

最小可复现代码:

JS代码

const App = () => {
    const [timeline, setTimeline] = React.useState([]);
    let timelineTemp = ['Hi'];
    
    React.useEffect(() => {
        timelineTemp.push(
            <button key="static" onClick={update}>Update</button>
        );
        setTimeline([...timeline, ...timelineTemp]);
    }, []);
    
    const update = () => {
        setTimeline([...timeline, 'Bye']);
    };
    
    return timeline;
};
    
ReactDOM.render(<App />, document.getElementById("root"));

HTML代码

<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>

问题原因

核心是闭包捕获旧状态值:

  • 组件首次渲染时,update函数捕获了当时的timeline初始状态(空数组)。
  • 后续点击按钮调用update时,始终使用的是首次渲染时捕获的旧timeline值,而非最新状态,导致每次更新都是基于空数组拼接'Bye',看起来像是替换了原有内容。

解决方案

使用React的函数式状态更新,直接基于最新的前序状态进行修改,避免闭包带来的旧值问题:

修改update函数为:

const update = () => {
    setTimeline(prevTimeline => [...prevTimeline, 'Bye']);
};

修改后的完整JS代码

const App = () => {
    const [timeline, setTimeline] = React.useState([]);
    let timelineTemp = ['Hi'];
    
    React.useEffect(() => {
        timelineTemp.push(
            <button key="static" onClick={update}>Update</button>
        );
        setTimeline([...timeline, ...timelineTemp]);
    }, []);
    
    const update = () => {
        // 使用函数式更新,基于最新的前序状态追加内容
        setTimeline(prevTimeline => [...prevTimeline, 'Bye']);
    };
    
    return timeline;
};
    
ReactDOM.render(<App />, document.getElementById("root"));

这样每次点击按钮时,都会基于当前最新的timeline状态去追加'Bye',实现预期的追加效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 18:55:30