React limits the number of renders to prevent an infinite loop Error

Viewed 64

Below is my code

function App() {
    const [isImportant, setIsImportant] = useState("Yes")
    
    
    function handleClick() {
        setIsImportant("No")
    }
    
    return (
        <div className="state">
            <h1 className="state--title">Is state important to know?</h1>
            <div className="state--value" onClick ={setIsImportant("No")} >
              {isImportant}
            </div>
        </div>
    )
}

enter image description here

However I get the error which says 'Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.'

If someone can explain why the error is happening it would be grateful!!

3 Answers

Problem

Looking at your current code, this part:

onClick ={setIsImportant("No")}

is calling setIsImportant every time your page renders, and because this function modifies state of your component, it tries to re-render the same component again, causing an infinite loop.

Solution

There are two ways of solving this issue, either by wrapping setIsImportant method in a wrapper:

 <div className="state--value" onClick ={() => setIsImportant("No")} >
                  {isImportant}
    </div>

or by simply using the function you just created:

<div className="state--value" onClick ={handleClick} >
              {isImportant}
</div>

The onClick handler needs a function -- but what you pass is the result of calling setIsImportant("No"), thus setIsImportant("No") is called immediately when rendering.

To fix, pass a function instead. You actually already have one -- handleClick -- so use onClick={handleClick}.

  • You are invoking the setIsImportant in onClick directly
  • Everytime render happens setIsImportant("No") will be fired and setState causes the component to re-render and then re-rendering will fire setIsImportant("No") again and so on.. which leads to infinite re-render.
  • You are setting the state again and again and it never stops.

Solution

To prevent this you need to pass a function to onClick handler

onClick ={() => setIsImportant("No")}
Related