【问题标题】:Local copy of React prop is read-onlyReact prop 的本地副本是只读的
【发布时间】:2017-01-11 03:48:22
【问题描述】:

假设我有两个组件。父对象作为属性传递给对象,然后将其复制到本地数据存储中。它具有更新此本地存储的功能,该存储被传递给子级。这是我的父组件:

const Parent = ({stuff}) => {
  const store = {
    stuff: Object.assign({}, stuff);
  }

  const updateStuff = (thing, property) => store.stuff[thing].property = thing;

  return <Child stuff={stuff} updateStuff={updateStuff} />
}

子组件具有类似的结构——它复制stuff,并在&lt;input&gt;onChange 上改变其stuff 的副本。然后它将自己更新的内容副本传递给它收到的updateStuff 函数,以改变父项的道具副本。这是孩子。

const Child = ({stuff, updateStuff}) => {
  const stuff = {
    thing1: Object.assign({}, stuff.thing1),
    thing2: Object.assign({}, stuff.thing2)
  }

  const setProp = event => {
    const update = event.target.value;

    stuff.thing1.prop = update;
    updateStuff(thing1, stuff.thing1.prop)
  }

  return (
    <div>
      <input id="thing1" onChange={setProp} />
      <input id="thing1" onChange={setProp} />
    </div>
  )
}

注意,我使用 Object.assign 基本上克隆了 stuff 属性或其子属性,视情况而定。原因:React prop 是只读的,因此我需要创建一个克隆以进行更改,然后再将其传递回以改变应用程序的状态(此处未显示)/

现在,这适用于子组件——setProp 改变了stuff 的正确属性,通过登录控制台确认。但是,当方法到达 updateTeam 时,我收到一条错误消息:Uncaught TypeError: Cannot assign to read only property 'side' of object '#&lt;Object&gt;'

然而,两个组件都使用相同的原则:我不是在改变 prop,而是在改变本地存储的 prop 克隆。为什么这对 Child 有效,但对 Parent 无效?

【问题讨论】:

  • 这可能是 Object.assign 只做浅拷贝的结果。 Object.asssign reference。你能在你做 Object.assign() 的任何地方尝试深度克隆对象吗?类似newStuff: JSON.parse(JSON.stringify(stuff))。我的想法是对象的较低级别部分并不是真正的副本。
  • 这实际上解决了问题。如果您将其格式化为答案,我很乐意接受它作为正确答案。
  • 所以我猜我的 Parent 组件中 stuff 的属性实际上是对实际 stuff 属性的属性的引用。这是一个正确的分析吗,@BrandonRoberts?
  • 为什么同样的事情不适用于我的子组件?
  • 如果在 App.js 中启用了严格模式,则可以使用 let 代替 constconst stuff = { thing1 -> 到 let stuff = { thing1

标签: javascript reactjs


【解决方案1】:

Object.assign 只做一个 prop Object.assign Reference 的浅拷贝。为了制作道具的真正深拷贝(并消除错误),您可以使用newStuff: JSON.parse(JSON.stringify(stuff)) 进行深拷贝。很高兴这有帮助!

这背后的真正原因在一个例子中给出:

let original = {
    name: 'Test',
    nestedObj: {
        (...some properties)
    }
}

在上面的示例中,原始对象属性“名称”是一个新副本,但嵌套对象仍然是对原始对象的引用。这样,当您尝试编辑嵌套对象的一部分时,它会引用原始对象并大喊它是不可变的。

【讨论】:

  • 非常感谢...我仍然不确定为什么 Child 没有发生同样的事情 - 考虑到我也在改变 thing 的属性(属性)。无论如何,谢谢。
  • 这里是深拷贝与浅拷贝的一个很好的答案:stackoverflow.com/questions/184710/…。当我在 react 中遇到类似问题时,这对我很有帮助。
  • 您先生是一个优质用户。
【解决方案2】:

尝试将 const 更改为 let 以获取本地副本

【讨论】:

  • 不——const thing 仅表示它不是一个变量,因此thing 不能被重新分配——所以,如果我说const thing = { prop: 'value'},我不能重新分配thing,但我可以更改thing.prop 的值。
  • 您是否正确分配了属性? store.stuff[thing].property 应该类似于 store.stuff[thing][property] 吗?
  • 没有。这是 React 特有的问题。
猜你喜欢
  • 1970-01-01
  • 2017-08-13
  • 2021-01-19
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
  • 2014-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多