How to Fix "Too Many Re-renders" Error in React


I ran into this simple React error, which was telling me that I had too many re-renders and that I was approaching an infinite render loop.

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

This is a simple example of what could trigger this error.

const Component = () => {
  const [open, setOpen] = useState(false);
  return (
    <>
      <button onClick={setOpen(!open)}>Toggle!</button>
      <span>{open.toString()}</span>
    </>
  );
};

It seems as though we are calling our state setter (setOpen in this case) immediately after render. These state setters will re-invoke the render process, which will then call our state setter again, which will force a re-render again, and so on.

Solution and Explanation

The issue with our code is that our state setter is being invoked immediately upon render, which means something isn’t acting as expected.

In this scenario, the onClick={setOpen(!open)} fires upon render instead of onClick, creating this infinite loop.

In order to fix this, we can “add an event” to our event handler by changing the onClick handler to be onClick={(event) => setOpen(!open)}.

We won’t include the event parameter since it’ll be unused.

const Component = () => {
  const [open, setOpen] = useState(false);
  return (
    <>
      <button onClick={() => setOpen(!open)}>Toggle!</button>
      <span>{open.toString()}</span>
    </>
  );
};

Extracting the Handler

Another solution could be to extract the handler out into a function.

const Component = () => {
  const [open, setOpen] = useState(false);
  const handler = () => {
    setOpen(!open);
  };
  return (
    <>
      <button onClick={handler}>Toggle!</button>
      <span>{open.toString()}</span>
    </>
  );
};