This warning can often happen when a component sets the state inside the useEffect
hook. The useEffect
hook either does not have a dependency array or has the changing state variable as a dependency. That makes the useEffect
hook execute in an infinite loop.
useEffect without dependency array
Take a look at the below code. I have a useEffect
with no dependency array. That means the effect runs for every component re-render.
import { useEffect, useState } from "react"
export const InputBox = () =>{
const [inputType, setInputType] = useState(false)
useEffect(() => {
setInputType(!inputType) // Creates an infinite loop
})
return(
<>
{inputType}
</>
)
}
When the component renders for the first time, the useEffect
executes and sets the inputType
to the opposite value it had before. That causes a component re-render because the setInputType(!inputType)
results in a state update and guarantees another useEffect
execution. This cycle creates an infinite loop.
Having a changing state variable as a dependency
In this scenario, I do have a dependency array. But my dependency array contains one of the state variables that I change inside the useEffect
hook.
import { useEffect, useState } from "react"
export const InputBox = () =>{
const [inputType, setInputType] = useState(false)
useEffect(() => {
setInputType(!inputType)
},[inputType]) // Creates an infinite loop
return(
<>
{inputType}
</>
)
}
Note that I have the inputType
state variable in the dependency array while I update the same variable in the useEffect
hook. This scenario creates the same infinite loop as the previous example did.
How to avoid the “Maximum update depth exceeded” warning?
If your useEffect
hook updates state variables, always use a dependency array as the second argument to the useEffect
hook. Do not use state variables you update inside the useEffect
hook as arguments in the dependency array. If you don’t have any qualifying dependencies, use an empty array to avoid infinite loops.