I would like to know the difference between the following two versions of code. Both versions do the same.
1) Here just the counter variable is used to get the current value
const Counter = () => {
const [counter, setCounter] = useState(0);
return <button onClick={() => setCounter(counter + 1)}>{counter}</button>;
}
2) This version passes a function to setCounter
const Counter = () => {
const [counter, setCounter] = useState(0);
return <button onClick={() => setCounter(c => c + 1)}>{counter}</button>;
}
The official documentation says:
If the new state is computed using the previous state, you can pass a function to setState. The function will receive the previous value, and return an updated value.
So what's wrong with the first option? Are there some pitfalls?
With the particular code in your example, you have the previous value in hand, so there isn't much difference. But sometimes you don't. For example, suppose you wanted to have a memoized callback function. Due to the memoization, the value of counter gets locked in when the closure is created, and won't be up to date.
const Counter = () => {
const [counter, setCounter] = useState(0);
// The following function gets created just once, the first time Counter renders.
const onClick = useCallback(() => {
setCounter(c => c + 1); // This works as intended
//setCounter(counter + 1); // This would always set it to 1, never to 2 or more.
}, []); // You could of course add counter to this array, but then you don't get as much benefit from the memoization.
return <button onClick={onClick}>{counter}</button>;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With