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

React JS中如何修改子对象属性?控制台打印异常求助

问题分析与解决方案

为什么会出现console.log不一致的情况

浏览器控制台打印引用类型(对象/数组)时,存储的是对象的引用而非打印瞬间的快照。当你展开父对象(newDisplayedAssignment[key])时,控制台会实时读取当前对象状态,若修改操作和控制台展开存在时间差,就可能显示旧值;而直接打印子对象(newDisplayedAssignment[key][assignment])时,控制台会立即截取该子对象的快照,因此能显示正确的新值。

但更核心的问题是你违反了React的不可变数据原则:直接修改传入的对象(哪怕变量名带new)不会触发组件重新渲染,还可能导致状态混乱,这也是你之前深度复制没效果的大概率原因——复制方式不对,没做到真正的深层独立副本。

正确的不可变更新方式

必须创建对象的深层副本,修改副本后返回,确保每一层都是新引用,以下是几种可行实现:

方法1:使用展开运算符逐层复制

function onDateChange(event, newDisplayedAssignment, key, assignment) {
  // 逐层创建新对象,保证每一层引用都独立
  const updatedAssignments = {
    ...newDisplayedAssignment,
    [key]: {
      ...newDisplayedAssignment[key],
      [assignment]: {
        ...newDisplayedAssignment[key][assignment],
        date: event.target.value
      }
    }
  };
  
  console.log(updatedAssignments[key][assignment]);
  console.log(updatedAssignments[key]);
  return updatedAssignments;
}

方法2:使用structuredClone做深度复制(现代浏览器支持)

function onDateChange(event, newDisplayedAssignment, key, assignment) {
  // 深度复制整个对象,生成完全独立的副本
  const updatedAssignments = structuredClone(newDisplayedAssignment);
  updatedAssignments[key][assignment]['date'] = event.target.value;
  
  console.log(updatedAssignments[key][assignment]);
  console.log(updatedAssignments[key]);
  return updatedAssignments;
}

方法3:自定义递归深度复制(兼容旧环境)

如果运行环境不支持structuredClone,可以自己实现深度复制函数:

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));
  const clonedObj = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      clonedObj[key] = deepClone(obj[key]);
    }
  }
  return clonedObj;
}

function onDateChange(event, newDisplayedAssignment, key, assignment) {
  const updatedAssignments = deepClone(newDisplayedAssignment);
  updatedAssignments[key][assignment]['date'] = event.target.value;
  
  console.log(updatedAssignments[key][assignment]);
  console.log(updatedAssignments[key]);
  return updatedAssignments;
}

额外注意事项

  • 调用这个函数后,必须将返回的新对象设置为React状态(比如通过setState或useState的更新函数),否则组件不会重新渲染,界面也不会同步变化。
  • 之前深度复制没效果,大概率是用了浅复制方式(比如Object.assign仅复制第一层、展开运算符只处理外层),必须确保修改的是完全独立的深层副本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 15:57:20