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

React.js复制对象数组为state时原引用被修改问题求解

问题原因

你之前使用的两种写法都属于浅拷贝,最多只能拷贝最外层1-2层的结构:

  • [...USERS_TYPE] 仅拷贝了最外层的数组,数组内的用户对象、inputs数组、inputs内的配置对象全部和原USERS_TYPE共享引用
  • USERS_TYPE.map(item=>({...item})) 仅额外拷贝了外层的用户对象,内部的inputs数组和数组内的配置对象仍然是原引用
    所以修改内层属性时,会直接改动原常量的值。
解决方案

方案1:逐层手动拷贝(性能最优,适合固定结构场景)

State初始化阶段

逐层拷贝所有嵌套的对象和数组:

const [users, setUsers] = useState(
  USERS_TYPE.map(user => ({
    ...user,
    // 拷贝inputs数组,同时拷贝数组内每个输入配置对象
    inputs: user.inputs.map(input => ({...input}))
  }))
)

State修改阶段

不要直接修改原引用的属性,修改时也要逐层返回新对象:

const changes = users.map((user, idx) => {
  // 非选中项直接返回原对象,不做修改
  if (idx !== selected - 1) return user
  const errIndexList = validation(user.inputs)
  // 生成新的inputs数组,错误项返回新的配置对象
  const newInputs = user.inputs.map((input, inputIdx) => {
    return errIndexList.includes(inputIdx) ? {...input, error: true} : input
  })
  // 返回新的用户对象
  return {...user, inputs: newInputs}
})
setUsers(changes)

方案2:原生深拷贝(写法简单,适合嵌套层级复杂的场景)

如果结构嵌套层级多,手动逐层拷贝太麻烦,可以直接用浏览器原生的structuredClone方法做深拷贝,你的场景里都是普通字符串、布尔值、数组、对象,完全兼容:

// 初始化时直接深拷贝原常量
const [users, setUsers] = useState(structuredClone(USERS_TYPE))

注意:structuredClone不支持拷贝函数、Symbol、循环引用等特殊类型值,普通业务配置场景都可以正常使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 10:54:03