Let's say I have two Components. The parent is passed an Object as a property, which it then copies into local data store. It has a function to update this local store, which gets passed down to a child. Here is my parent Component:
const Parent = ({stuff}) => {
const store = {
stuff: Object.assign({}, stuff);
}
const updateStuff = (thing, property) => store.stuff[thing].property = thing;
return <Child stuff={stuff} updateStuff={updateStuff} />
}
The Child Component has a similar structure -- it makes a copy of stuff
, and mutates its copy of stuff
on an <input>
's onChange
. It then passes its own updated copy of stuff to the updateStuff
function it received, in order to mutate the Parent's copy of the prop. Here is the Child.
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>
)
}
Notice, I've used Object.assign to basically clone the stuff
prop or its child properties, as the case necessitates. The reason for this: a React prop is read-only, and thus I need to create a clone to make changes on before passing it back to mutate the app's state (not shown here)/
Now, this works on the Child component -- setProp
mutates the correct property of stuff
, confirmed by logging to the console. However, when the method gets to updateTeam
, I get an error message : Uncaught TypeError: Cannot assign to read only property 'side' of object '#<Object>'
Yet, both Components use the same principle: I am not mutating the prop, but rather I am mutating a locally-stored clone of the prop. Why does this work for Child, but not for Parent?