嵌套对象及数组层级下带动态键的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
相关产品推荐
相关产品推荐

