Wanting to improve my understanding of React in functional components I've seen some that pass a seState
with a function when spreading an array or object. When I reference the docs I see:
Unlike the
setState
method found in class components,useState
does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax
So I'm trying to understand why this implementation:
const [count, setCount] = useState([initialCount]);
setCount([...count, newCount])
is not the preferred when it comes to arrays and objects and this:
const [count, setCount] = useState([initialCount]);
setCount(prevCount => [...prevCount, newCount])
is the preferred. In my research for an answer I haven't found an answer about this and I've read through:
setState
that takes (state, props)
as an argument to update state, using React Hook?The only conclusions I can establish the need for the function is:
Why when it comes to arrays and objects in a useState
it should be passed with a function opposed to what's commonly used?
Its probably best practice to pass a function to the useState
dispatch to avoid renders getting out of sync, especially if you use asynchronous methods to update state, but also any time your new state is dependent on previous state (so like even incrementing numbers, not just for objects and arrays).
As Kent C. Dodds illustrates, there are issues as it comes to closures and the timing of rendering and function calls when the new state update is dependent upon previous state.
If you want to merge your data with previous state, you want to be sure to merge with the latest state (as of that particular merge call). The setState dispatch
provides the previous state as the first parameter. You can be certain that this is the latest state (for that merge) and you won't get out of sync data, or out of order updates.