function Counter() {
const [count, setCount] = useState(0);
const [calculation, setCalculation] = useState(0);
useEffect(() => {
setCalculation(() => count * 2);
}, [count]); // <- add the count variable here
return (
<>
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>+</button>
<p>Calculation: {calculation}</p>
</>
);
}
What I don’t understand in this function is,
setCalculation(() => count * 2); setCount((c) => c + 1);
They do the similar work, but why does the first line NOT have the parameter? Does this make any difference between two lines?
And also why does it use ‘c’, not ‘count’? (While ‘count’ was used in the earlier line.)
Thank you.
I thought they do the same work but I’m not sure now
The two have a subtle difference in where the current value of count comes from.
When you write
setState(() => count*2)
// or
setState(count * 2)
The count
value is captured from the current render into a closure. The main implication is that using the count
value to update state does not guarantee that you have the latest.
This matters in cases where setters might run out of order such as async operations, concurrent renders, etc.
The simplest demonstration of the difference is by doing multiple calls together:
// Assume count is initially 5
setState(count * 2) // count is 10
setState(count * 2) // count is _still_ 10, because the `count` variable is still 5
Versus:
// Assume count is initially 5
setState(count => count * 2) // count is 10
setState(count => count * 2) // count is 20
The callback format guarantees that you get the latest value.
As a recommendation, whenever your new state depends on the old state, access it via callback.