javascriptreactjsreact-hooks

React useState hook, calling setState with function


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.


Solution

  • 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