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

嵌套对象及数组层级下带动态键的state更新实现问题

解决方案

核心是遵循React状态更新的不可变性原则,所有嵌套层级都要做浅拷贝,配合动态属性名语法实现字段的动态更新。

函数组件useState写法(易读版,推荐新手用)

setSingleCarers(prev => {
  // 拷贝rosters数组
  const newRosters = [...prev.rosters];
  // 拷贝目标排班条目
  const targetRoster = {...newRosters[indexOfRoster]};
  // 拷贝schedule对象
  const newSchedule = {...targetRoster.schedule};
  // 拷贝目标星期的调度对象
  const targetDaySchedule = {...newSchedule[dayOfRoster]};
  // 更新对应start/finish字段
  targetDaySchedule[name] = value;

  // 逐层回赋值
  newSchedule[dayOfRoster] = targetDaySchedule;
  targetRoster.schedule = newSchedule;
  newRosters[indexOfRoster] = targetRoster;

  // 返回全新的state对象
  return {
    ...prev,
    rosters: newRosters
  };
})

简洁版写法(嵌套展开运算符)

setSingleCarers(prev => ({
  ...prev,
  rosters: prev.rosters.map((roster, idx) => 
    idx === indexOfRoster ? {
      ...roster,
      schedule: {
        ...roster.schedule,
        [dayOfRoster]: {
          ...roster.schedule[dayOfRoster],
          [name]: value
        }
      }
    } : roster
  )
}))

类组件setState写法

this.setState(prev => ({
  singleCarers: {
    ...prev.singleCarers,
    rosters: prev.singleCarers.rosters.map((roster, idx) => 
      idx === indexOfRoster ? {
        ...roster,
        schedule: {
          ...roster.schedule,
          [dayOfRoster]: {
            ...roster.schedule[dayOfRoster],
            [name]: value
          }
        }
      } : roster
    )
  }
}))

注意事项

  • 不要直接修改原state的属性,比如prev.rosters[indexOfRoster].schedule[dayOfRoster][name] = value这种写法会触发状态不更新的问题。
  • 动态属性用方括号[]包裹变量即可实现字段的动态指定,不需要写死key名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 17:24:03