Why doesn't the React useState hook work in a for loop?

Viewed 2193

I'm curious about why setting state in a for loop doesn't work as expected.

This is my code using hooks.

const [count, setCount] = useState(0);

  const onButtonPress = () => {
    for(let i=0; i<100; i++){
      setCount(i);
    }
  }

  useEffect(()=> {
    console.log('useEffect called');
    console.log(count);
  },[count])

I call the onButtonPress function on a button click.

Behavior I expect: count state shoukd update 100 times and consequently call the useEffect hook a 100 times.

Actual behavior: The useEffect hook is being only called once after the last iteration of the loop.

I know that the official react docs say that hooks shouldn't be used in loops but their explanation isn't very clear.

I want to understand why calling setCount in a loop doesn't work.

NOTE: I know that there are other methods to achieve the desired result but I'm interested in understanding why the setCount wouldn't be called multiple times.

2 Answers

state updates are batched by react, so if you call the same state updater many times in your handler, the entire operation will be batched and a single update will be performed which is what you witness

Also when the docs say that the hooks shouldn't be used within loops they mean by hooks such as useState, useRef, useEffect and so on and not the state updater being returned by useState hook

React dispatches the state changes in batch, when running a for loop it quickly batches 100 requests resulting in only 1 state update and eventually 1 re-render. If you use setTimeout event with 0ms, you'd able to get the required but I'm not totally sure about your use-case.

Related