ReactJs中如何更新嵌套对象数组类型的state状态
React 嵌套state更新实现方案
React 更新嵌套结构的 state 必须遵循不可变更新规则,不能直接修改原 state 上的对象或数组,否则 React 无法检测到 state 变化触发重渲染,需要逐层拷贝结构后修改目标字段,再将新的 state 传入更新函数。
核心实现代码
以下是按钮点击时,向指定选项的childOptions数组追加新对象的完整实现:
import { useState } from 'react'; import { v4 as uuid } from 'uuid'; // 原有state定义 const [select1, setSelect1] = useState({ id: uuid(), type: 'select', properties: { label: 'Select1', options: [], }, parentId: null, }); // 按钮点击处理函数,入参为要添加子选项的目标选项id const handleAddChildOption = (targetOptionId) => { // 用函数式更新拿最新的state值,避免闭包导致的旧值问题 setSelect1(prevState => { return { // 拷贝最外层state属性 ...prevState, properties: { // 拷贝properties层属性 ...prevState.properties, // 遍历options数组,找到目标选项做更新 options: prevState.properties.options.map(option => { if (option.id === targetOptionId) { return { // 拷贝原选项的所有属性 ...option, // 生成新的childOptions数组,追加新的子选项对象 childOptions: [ ...option.childOptions, { id: uuid(), optionName: '新子选项', value: '', childOptions: [] // 子选项支持嵌套时可保留该字段 } ] } } // 非目标选项直接返回原对象即可 return option; }) } } }) }
按钮绑定方式
如果要给某个选项加子选项,把对应选项的id传入处理函数即可:
<button onClick={() => handleAddChildOption(对应选项的id)}> 给该选项添加子选项 </button>
如果你是按数组索引定位目标选项,只需要把入参改成目标索引,把map里的判断条件从option.id === targetOptionId改成index === targetOptionIndex即可。
注意事项
- 禁止直接用
push、splice等方法直接修改原state上的数组,这类方法会修改原数组引用,React无法识别state变化 - 所有嵌套的对象、数组更新时都要做浅拷贝,避免意外修改原state导致的不可预期bug
- 嵌套层级较深的场景如果觉得逐层拷贝写起来繁琐,也可以用
immer这类库简化不可变更新的写法,原生JS按上面的写法已经可以完全实现需求
内容的提问来源于stack exchange,提问作者Amritpal Singh
相关产品推荐
相关产品推荐

