How to fully replace one array by new in react useState();
For example how right to do this:
const [colors, setColors] = useState(['#FF9A00', '#6276d5', '#18B8FB']);
const onChangeColors = (newValue) => {
setColors(prevState => [...newValue]);
}
return (<div style={{ width: '500px', margin: 'auto' }}>
<h2>Current Color:</h2>
{
colors.map((color) => (<p>{color}</p>))
}
<ColorPicker colors={colors} onChange={newValue => onChangeColors(newValue)}/>
</div>);
CodePudding user response:
What you're doing is right. But if you wanna simplify further use a inline arrow function:
const [colors, setColors] = useState(['#FF9A00', '#6276d5', '#18B8FB']);
return (
<div style={{ width: '500px', margin: 'auto' }}>
<h2>Current Color:</h2>
{
colors.map((color) => (<p>{color}</p>))
}
<ColorPicker colors={colors} onChange={newValue => setColors(newValue)}/>
</div>);
CodePudding user response:
How to fully replace one array by new in react useState();
by just setting it setState(newValue);
Let's go step by step:
[...newValue]
this creates a copy ofnewValue
. ButnewValue
is already a new value (I'd assume by the name). So we don't need to copy the array.which leaves us with
setColors(prevState => newValue)
. but since we don't interact withprevState
we don't need the function at all and can just pass thenewValue
.now we're at
const onChangeColors = (newValue) => { setColors(newValue); }
but do we really needonChangeColors
? All it does is forward the argument it gets tosetColors
. We can simply replace it:const onChangeColors = setColors;
onChange={newValue => onChangeColors(newValue)}
that's the same as the step before, this function is also just forwarding the argument.
which effectively leaves us with: <ColorPicker colors={colors} onChange={setColors} />
But that's for this special case where onChange
passes the new value, not like an event-object and you want to replace the old state, not append to it or something.
const [colors, setColors] = useState(['#FF9A00', '#6276d5', '#18B8FB']);
return (<div style={{ width: '500px', margin: 'auto' }}>
<h2>Current Color:</h2>
{
colors.map((color, index) => (<p key={index}>{color}</p>))
}
<ColorPicker colors={colors} onChange={setColors} />
</div>);
CodePudding user response:
What is mutation?:
In essence, the concept of mutability describes whether or not the state of an object can be modified after it has been declared.
Numbers, strings, and boolean values are
immutable
, meaning unchangeable or “read-only in Javascript. Hovewer, it is technically possible to change the content of object (thereforearrays
itself, which causes mutation.
Why not to mutate?:
- There're couple different points why not to mutate data at all but, it's plainly more of stritctly applied best practice in order to not to cause another possible problem(s).
Then what to do?:
In order to achieve immutability with
useState hook
(or similarlysetState method
with class component), it's needed to be setting state via creating a new object.Incase it's desired to keep previous state of an array within new one, previous state should be kept e.g. iterating over with a spread operator
...prevState
. And only after then, new value(s) should be placed right after it like below;
const onChangeColors = (newValue) => {
setColors(prevState => [...prevState, ...newValue]);
}
- Incase you don't want to keep the previous state of the array, then implementation is like below;
const onChangeColors = (newValue) => {
setColors([...newValue]);
}
To be short, the only thing for you to do differently is either;
- If you want previous state of an array, copying the previous state before adding the new value to new returning array,
- or only copying the new value into new returning array with
setState
function.