In the React docs (https://reactjs.org/docs/hooks-reference.html#usestate) it says "If the new state is computed using the previous state, you can pass a function to setState" like so:
const [count, setCount] = useState(initialCount);
setCount(prevCount => prevCount 1)
But why is React suggesting this as a solution when it can be done more succinctly using the count variable like so:
const [count, setCount] = useState(initialCount);
setCount(count 1)
This latter approach works even when working with mutable objects like arrays as in this example:
https://codesandbox.io/s/6b-array-subcomp-event-usestate-props-r032xv
CodePudding user response:
If you have a function that use SetCount twice, without using the prev state, it will setCount only once.
const [count, setCount] = useState(0);
const fun1 = () =>{
setCount(count 1)
setCount(count 1)
}
// it will change count to 1 rather than 2
That's why it's recommended to use prev state
CodePudding user response:
The suggestion to use a function is because you're assured to get a reliable previous state in its parameter. On the other side, if you are using a value of a state directly it might happen that you are reading its stale value as react's setState
operation is asynchronous and might still have not updated the state.
Here is an example:
function App() {
const [a, setA] = useState(0);
const [b, setB] = useState(0);
useEffect(() => {
setA(a 2);
setA(a 2);
}, []);
useEffect(() => {
setB((prev) => prev 2);
setB((prev) => prev 2);
}, []);
return (
<div>
<h1>{a}</h1>
<h1>{b}</h1>
</div>
);
}
a
will contain 2
because react will do both setA
at once (batch update) therefore reading previous state a
once, which is 0 at that moment.
b
, however, will have the correct value, 4
, as it explicitly uses the previous state provided by the updating functions parameter.