4

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.

1
  • 1
    Voting to reopen because the linked question is about the Component this.setState, and this question is about the functional useState's second return argument. They're entirely different. Commented Feb 23, 2022 at 14:01

2 Answers 2

1

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:

Functional updates

Sign up to request clarification or add additional context in comments.

2 Comments

This does not answer the question. You do not have access to the newly set state even when passing a function to useState, only the previous one.
I didn't say that there is an access the newly state at all when passing a callback, just saying that the second approach is useful when there is a need to update the new state based on the previous one.
0

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 setStateis 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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.