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

React useState自动更新问题求助:修改新状态却改动原状态

React状态意外更新问题分析与解决

问题根源

这不是useState钩子的问题,而是JavaScript引用类型的特性导致的:

  • 对象、数组属于引用类型,当你执行let newStatObj = statistikat[0];时,并没有复制一个新对象,只是把原对象的引用地址赋值给了newStatObj。
  • 后续修改newStatObj的嵌套属性时,本质是直接操作原对象的内存地址,所以statistikat里的对象也会被同步修改。

解决方案

要避免修改原状态,必须创建原对象的深拷贝,断开引用关联。以下是几种可行的深拷贝方式:

方式1:使用structuredClone(推荐,现代浏览器支持)

structuredClone是原生API,支持大多数类型的深拷贝,包括嵌套对象:

const [newStatsObj, setNewStatsObj] = useState(() => {
  let muaj;
  let cmimiPerDit;
  if (dtSot.getMonth() === 5) muaj = "qershor";
  if (dtSot.getMonth() === 6) muaj = "korrig";
  if (dtSot.getMonth() === 7) muaj = "gusht";

  if (dataForSpecific.dhoma === "dhomTeke") cmimiPerDit = 100;
  if (dataForSpecific.dhoma === "dhomCift") cmimiPerDit = 120;
  if (dataForSpecific.dhoma === "dhomFamiljare") cmimiPerDit = 150;

  // 深拷贝原对象,断开与statistikat的引用关联
  let newStatObj = structuredClone(statistikat[0]);

  // 修改拷贝后的对象,不会影响原statistikat
  newStatObj[`fitimetSezon${dtSot.getFullYear()}`][muaj][
    dtSot.getDate() - 1
  ] += Number(cmimiPerDit);

  return newStatObj;
});

方式2:使用JSON.parse(JSON.stringify())

如果你的对象里没有函数、Symbol、日期对象等特殊类型,可以用这种方式:

let newStatObj = JSON.parse(JSON.stringify(statistikat[0]));

注意:这种方式会丢失函数、Symbol,日期对象会被转成字符串,不适合复杂场景。

方式3:手动递归深拷贝

如果需要兼容旧浏览器,或者处理特殊类型,可以自己实现递归拷贝函数:

function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (obj instanceof Date) return new Date(obj.getTime());
  if (obj instanceof Array) return obj.map(item => deepClone(item));
  if (typeof obj === 'object') {
    const clonedObj = {};
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        clonedObj[key] = deepClone(obj[key]);
      }
    }
    return clonedObj;
  }
}

// 使用:
let newStatObj = deepClone(statistikat[0]);

注意事项

  • 浅拷贝(比如{...statistikat[0]})只能拷贝对象的第一层属性,嵌套的对象还是引用类型,修改内层属性依然会影响原状态,所以必须用深拷贝。
  • useState的初始化函数只会在组件首次渲染时执行一次,后续组件更新不会重新运行这个函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 02:52:33