Reputation: 3965
There is a concept in React (when using hooks) that confuses me.
I made a component for explanation (that increases a counter):
const [counter, setCounter] = useState(0); // counter hook
// code will follow
// render
return (
<div>
<button onClick={handleClick}>+</button>
<h3>{counter}</h3>
</div>
);
For the handler function, I have seen different options to set the state.
First method (using setState()
normally):
const handleClick = () => {
setCounter(counter + 1);
};
Second method (creating a function inside setState()
and returning the new value):
const handleClick = () => {
setCounter((counter) => {
return counter + 1;
});
};
I thought the difference would be that with the second method, you could immediately do a callback after setting the state, like this:
const handleClick = () => {
setCounter((counter) => {
return counter + 1;
}, () => {
console.log(counter); // trying callback after state is set
});
};
But when trying this (with both methods), the console displays the following error message:
Warning: State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect().
So I think in both cases, using useEffect()
as a callback on setState()
is the right way.
My question is: what is the difference between the two methods and what method is best to set the state. I have read about state immutability but can not immediately see how it would make a difference in this example.
Upvotes: 4
Views: 6704
Reputation: 3965
Since this question is gaining some attention I will add this example.
<button onClick={() => setCount(0)}>Reset</button>
<button onClick={() => setCount((prevCount) => prevCount - 1)}>-</button>
<button onClick={() => setCount((prevCount) => prevCount + 1)}>+</button>
You can see that for +
and -
the functional setState
is being used, this is because the new state value is computed using the previous state (you are adding/subtracting from the previous count value).
The reset
button is using the normal form, because it doesn't compute the new state value based on a computation on the old value, it always just sets it to a fixed number (for example 0
).
So in my case, the best thing to do would have been using the functional setState
.
Upvotes: 0
Reputation: 3231
In your case it's the same.
Basically when your state is computed with your previous state you can use the second approach which gets the previous value.
Have a look in React docs about this:
Upvotes: 1