I currently have a component that uses a selector with useSelector
from react-redux
. However, after I set the state with the selector value and then update the state with a onChange
event handler, they original selector value will be changed also.
How can I not mutate the original selector object when updating the state?
// Here is how the selectorObject looks
selectorObject = {
label: "Hello"
}
const ComponentA = () => {
const selectorObject = useSelector(getObjectSelector);
const [stateObject, setStateObject] = useState(null);
useEffect(() => {
if (selectorObject) {
setStateObject({...selectorObject})
{
}, [selectorObject])
const handleOnchange = (event, key) => {
const temp = {...selectorObject}
// Also tried `const temp = Object.assign({}, ...selectorObject)` but same result
temp['label'] = event.target.value; //Assume event.target.value = "Hello World"
setStateObject({...temp})
console.log(stateObject)
console.log(selectorObject)
}
}
The two console logs in the handleOnchange
function shows that both selectorObject
and stateObject
have been changed the same and the label proprty is equal to Hello World
What I’m expecting is for selectorObject.label
to still equal Hello
and stateObject.label
to equal the new value Hello World
I thought the spread operator does a deep clone and should not mutate the original
2
Answers
You
selectorObject
is a reference type (an object), spreading it to create a new object will not create a deep copy. BothstateObject
andselectorObject
end up pointing to the same object in memory and the situation you described happens.Just use lodash _.cloneDeep()
I think this problem occurs because of the property of ‘…’ funtion.
When using ‘…’, if the state object has nested objects, the nested objects will still reference the original object.
Try to change the code like this.