'React useState. Why do the docs advise passing a function with the previous state when setting the state?

In the React docs (https://reactjs.org/docs/hooks-reference.html#usestate) it says "If the new state is computed using the previous state, you can pass a function to setState" like so:

const [count, setCount] = useState(initialCount);
setCount(prevCount => prevCount + 1)

But why is React suggesting this as a solution when it can be done more succinctly using the count variable like so:

const [count, setCount] = useState(initialCount);
setCount(count + 1)

This latter approach works even when working with mutable objects like arrays as in this example:

https://codesandbox.io/s/6b-array-subcomp-event-usestate-props-r032xv



Solution 1:[1]

If you have a function that use SetCount twice, without using the prev state, it will setCount only once.

const [count, setCount] = useState(0);
const fun1 = () =>{
   setCount(count + 1)
   setCount(count + 1)
}
// it will change count to 1 rather than 2

That's why it's recommended to use prev state

Solution 2:[2]

The suggestion to use a function is because you're assured to get a reliable previous state in its parameter. On the other side, if you are using a value of a state directly it might happen that you are reading its stale value as react's setState operation is asynchronous and might still have not updated the state.

Here is an example:

function App() {
  const [a, setA] = useState(0);
  const [b, setB] = useState(0);
  useEffect(() => {
    setA(a + 2);
    setA(a + 2);
  }, []);
  useEffect(() => {
    setB((prev) => prev + 2);
    setB((prev) => prev + 2);
  }, []);
  return (
    <div>
      <h1>{a}</h1>
      <h1>{b}</h1> 
    </div>
  );
}

a will contain 2 because react will do both setA at once (batch update) therefore reading previous state a once, which is 0 at that moment.

b, however, will have the correct value, 4, as it explicitly uses the previous state provided by the updating functions parameter.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Moiz Sheikh
Solution 2