比方说,我有两个组件。父对象作为属性传递给对象,然后将其复制到本地数据存储中。它有一个功能来更新这个本地存储,它被传递给一个孩子。这里是我的父Component:React道具的本地副本是只读的
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
副本,变异上<input>
的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道具是只读的,因此我需要创建一个克隆来进行更改,然后再传递它以更改应用程序的状态(此处未显示)/
现在,子组件 - setProp
突变stuff
的正确属性,通过登录到控制台进行确认。然而,当方法得到updateTeam
,我得到一个错误信息:Uncaught TypeError: Cannot assign to read only property 'side' of object '#<Object>'
然而,这两个组件使用相同的原则:我没有突变道具,而是我突变本地存储的道具克隆。为什么这对儿童有用,但对父母不起作用?
这可能是Object.assign只做浅拷贝的结果。 [Object.asssign reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Deep_Clone)。你可以尝试在Object.assign()的任何地方深度克隆对象。类似于'newStuff:JSON.parse(JSON.stringify(stuff))'。我的想法是,对象的底层部分不是真正的副本。 –
这实际上解决了这个问题。如果您将此格式设置为答案,我会很乐意接受它作为正确答案。 –
所以我猜在我的父组件中'stuff'的属性实际上是对实际'stuff'属性的引用。这是一个正确的分析,@BrandonRoberts? –