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

React中状态对象添加至另一状态后原有对象被意外修改的问题

问题原因与解决方法

你的问题核心是没遵循React状态的不可变性原则,对象、数组这类引用类型,直接修改原状态或复用引用会引发两个问题:一是React检测不到状态变化,无法触发重渲染;二是共享的引用会让之前存入数组的对象被意外修改。

具体错误点:

  1. 修改状态a时直接篡改原对象
    Object.assign(a, { hello: event.target.value })会直接修改原状态对象a,而非创建新对象。这导致a的引用始终没变,后续存入数组b的都是同一个对象引用,修改输入框时会同步改变数组里所有指向该引用的元素。

  2. 更新数组b时复用原数组引用
    const newB = b只是复制了数组的引用,newB.push(a)修改的还是原状态数组,setB(newB)因为引用未变,React不会识别为状态更新;再加上数组里的元素都是a的同一个引用,自然会跟着a的修改而变化。

修正后的代码:

export default function () {
  const [a, setA] = useState({ hello: "world" });
  const [b, setB] = useState([]);

  const Submit = () => {
    // 创建新数组,添加当前a的对象
    setB([...b, a]);
    console.log(b);
  };

  return (
    <>
      <input
        type="text"
        onChange={(event) => {
          // 创建新对象,替换原状态a
          setA({ ...a, hello: event.target.value });
        }}
      />
      <button onClick={Submit}>Submit</button>
    </>
  );
}

关键修改说明:

  • 更新a时使用对象展开运算符{ ...a, hello: event.target.value },创建一个包含原对象所有属性、同时覆盖hello的新对象,保证每次修改都是新的引用。
  • 更新b时使用数组展开运算符[...b, a],创建原数组的副本并添加新元素,既避免修改原数组,又能让React检测到状态变化。

如果要处理嵌套对象,同样要保证每一层都是新的引用,比如嵌套对象修改时要逐层展开创建新对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 02:00:06