修改React JS嵌套结构state的正确方式:是否只需深拷贝变更对象?
你当前的state结构示例如下(已修正原JSON语法小问题):
{ user: { auth: true, sub_sq: [ { "1": { createdAt: "2021-08-28" } } ] }, sub: { name: "123", sub_sq: [ { "1": { createdAt: "2021-08-21" } } ] } }
问题1解答
不需要深拷贝整个根state对象。全量深拷贝会造成不必要的性能开销,还会导致依赖未变更字段(例如此处的sub对象)的组件触发无意义重渲染,完全没有必要。
问题2解答
仅拷贝变更链路的对象完全符合React state更新规范,你的做法是正确的。
React状态更新的核心要求是不可变性:只要修改了某个节点的值,该节点本身以及它往上的所有父级节点都需要生成新的引用,未被修改的节点可以直接复用原有引用即可,不需要额外拷贝。
举个实际更新示例,如果你要修改user下的auth字段,更新写法如下:
setState(prev => { return { ...prev, // 根节点生成新引用,未变更的sub字段直接复用原有引用 user: { ...prev.user, // user节点生成新引用 auth: false // 变更目标字段 } } })
如果要修改的是user.sub_sq内的属性,也只需拷贝变更链路的节点即可:
setState(prev => { return { ...prev, user: { ...prev.user, sub_sq: [ ...prev.user.sub_sq.slice(0, 1), // 数组前半部分复用 { ...prev.user.sub_sq[1], "1": { ...prev.user.sub_sq[1]["1"], createdAt: "2024-01-01" // 变更目标字段 } }, ...prev.user.sub_sq.slice(2) // 数组后半部分复用 ] } } })
这种写法既满足React的不可变更新要求,不会出现状态更新不生效的问题,也能最大程度避免不必要的组件重渲染,性能更优。
内容的提问来源于stack exchange,提问作者JOJU
相关产品推荐
相关产品推荐

