Ever tried to update object or array state directly in React?
I did that, the state of my component didn't change.
Destructuring the object/array was the solution.
When you update the state, create a new array/object by destructuring the one in the state, manipulate it then set it as a new value in the state.
Object
import React, { useState } from 'react';
const States = () => {
const [objectValue, setObjectValue] = useState({});
const updateObjectValue = (key, value) => {
// Destructure current state object
const objectvalue = {
...objectValue,
[key]: value,
};
setObjectValue(objectvalue);
};
return <Component/>;
};
export default States;
Array
import React, { useState } from 'react';
const States = () => {
const [arrayValue, setArrayValue] = useState([]);
const updateArrayValue = (value) => {
// Destructure current state array
const arrayvalue = [ ...arrayValue ];
arrayvalue.push(value);
setArrayValue(arrayvalue);
};
return <Component/>;
};
export default States;
Top comments (7)
Hi, Great Share!
Another hack is to use JSON.parse and JSON.stringify.
Consider the below function which deeply copies any value , no matter how nested it is.
function deepCopy(a) {
return JSON.parse(JSON.stringify(a));
}
Example -
Or even better, use immutable data structures, for example
Record
andList
from Immutable.js, or Drafts from Immer.js.Yes
Or use array methods like concat so you're not increasing your time complexity using iterator semantics.
Your Array example is not updating state as you intended due to poor nomenclature. If you have to spread you can just
setState(value => [ ...value, someNewValue ]);
, which IMO is better served bysetState(value => value.concat(someNewValue));
where the latter is using array semantics not iterator semantics.Good point.
But my point is when you want to update array state, don't act on the array state directly, you need to create another array from the state array and there are multiple solutions for that, I chose destructuring. that's all.
Raphael , Thanks for this sol
You are welcome