skip to Main Content

According to the React official documentation, setState should only trigger a re-render if the current value differs from the new one. However, I’ve encountered a scenario where my code enters an infinite loop, even though the same value is being set. Here’s the code snippet for reference:

import { useState } from "react";

export default function App() {
  const [count, setCount] = useState(1);
  setCount(1);
  return (
    <>
      <h1>{count}</h1>
    </>
  );
}

In this example, the code falls into an infinite loop, which seems counterintuitive based on my understanding of setState.

I hypothesize that when the logic in the component’s body encounters setCount(a);, a new render is scheduled. I would expect that after the current rendering completes, the reconciliation process would assess whether the new rendering is indeed necessary. Since the current state and the new value are identical (as per the Object.is comparison), no new render should be triggered.

Despite this, the code appears to enter an infinite rendering loop before the rendering cycle can complete.

My second hypothesis is that encountering a setState logic during the rendering process might cause the current rendering to be discarded and a new rendering to start. This is based on the observation that when I executed the following code, only "Rendering…" was printed, and "Didmount" and "Unmount" were not, indicating that rendering was restarted:

import { useState, useEffect } from "react";

export default function App() {
  const [count, setCount] = useState(1);
  setCount(1);
  console.log("Rendering...");

  useEffect(() => {
    console.log("Didmount");
    return () => {
      console.log("Unmount");
    };
  }, []);
  return (
    <>
      <h1>{count}</h1>
    </>
  );
}

However, I haven’t found specific documentation to substantiate this.

In summary, I’m seeking clarity on why attempting to change the state to the same value within the component body results in an infinite loop, even though such changes theoretically should not trigger a re-render.

Any clarification or guidance on this matter would be greatly appreciated. Thank you in advance for your insights!

2

Answers


  1. Components function’s code gets called by React to render the component.

    Setting state will cause the component to re-render.

    So, when React call your component, it renders and calls setCount(1) causing the component to re-render, so, again invoke setCount(1), etc. And here we have the loop.

    Solution is simply to remove that call, which will break the loop. You already are using initial value 1 with useState(1)

    Login or Signup to reply.
  2. The reason you get the infinite re-render is having setCount triggered whenever the component mounts. Aside from already setting the default value to one, the most natural way of mutating the state in this scenario will be doing this:

    import { useState, useEffect } from "react";
    
    export default function App() {
      const [count, setCount] = useState(1);
    
     
      return (
        <>
          <h1>{count}</h1>
          <button onClick={() => setCount(count + 1)}>Increase</button>
        </>
      );
    }
    
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search