2

Trying to update the state in the first render causes React to go into an infinite loop

Direct update:

function App() {
  const [state, setState] = useState(false);
  setState(false);
  return <div>hello</div>;
}

Result:

Too many re-renders. React limits the number of renders to prevent an infinite loop.

direct update sandbox

But it works fine when the update is run after a timeout

After timeout:

function App() {
  const [state, setState] = useState(false);
  setTimeout(() => {
    setState(false);
  }, 1000);
  return <div>hello</div>;
}

Results:

hello

after timeout sandbox

I know it's not good practice. The question is more about how it works than how to make it work.

Is the first render of useState somehow different?

Konrad
  • 21,590
  • 4
  • 28
  • 64
  • Interesting question. I'm puzzled by the difference between these two examples but I wouldn't express it the way you do about the first render somehow being different. What puzzles me most is, if you add a `console.log` to the top level of both components, the first one (as you would expect) logs many times before React reports the infinite loop and crashes, but the second one only logs twice. (And I assume it would be only once without Strict mode.) So the asynchronous update to the same value apparently doesn't cause a rerender - but I couldn't tell you why. I want to know myself, now! – Robin Zigmond Oct 11 '22 at 21:04
  • @RobinZigmond using `setState(false)` in an event handler also doesn't rerender the component https://codesandbox.io/s/gracious-bush-z3bpvg?file=/src/App.js – Konrad Oct 11 '22 at 21:07
  • thanks - this gets even more curious then! Is React automatically memoising the component? I thought you needed `React.memo` to make components check equality of props/state before rerendering. Whatever is happening I can't see why synchronous updates like your first example treat this differently. Am as interested in you in seeing answers :) – Robin Zigmond Oct 11 '22 at 21:10
  • 1
    I found this but still these answers don't really make sense to me : https://bitcoden.com/answers/why-does-setstate-in-the-body-of-the-component-cause-an-infinite-loop-even-if-its-setting-the-same-initial-value There are so many articles saying that React **won't** re-render when state stayed the same. – Tehila Oct 11 '22 at 21:35
  • 2
    It looks like you're causing react to restart the render cycle by triggering a change before the commit stage, `useEffect` was always the proper way forward (not a timeout) as it correctly inserts the update in the [lifecycle](https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/). – pilchard Oct 11 '22 at 21:41
  • 1
    And you where right with your explanation @pilchard. See this : https://stackoverflow.com/questions/74034014/updating-state-to-the-same-state-directly-in-the-component-body/74036012#74036012 – Tehila Oct 12 '22 at 03:22
  • @Tehila that's a good dupe, voting to close. (but why this question and yours both at the same time?) – pilchard Oct 12 '22 at 07:59
  • 1
    haha because we faced this issue when someone asked [this](https://stackoverflow.com/questions/74033629/react-native-infinite-re-render-when-setting-variable-to-same-value#comment130719264_74033629) and after discussing it in the comments there - each one of us asked the question without noticing :) – Tehila Oct 12 '22 at 08:05
  • Lols, makes sense, voted to close the original as a dupe as well. – pilchard Oct 12 '22 at 08:09

0 Answers0