0
0
ReactDebug / FixBeginner · 3 min read

How to Prevent Infinite Loop in useEffect in React

An infinite loop in useEffect happens when its dependency array changes on every render, causing repeated runs. To prevent this, ensure the dependency array only includes stable values or variables that truly need to trigger the effect, and avoid updating state inside useEffect without proper conditions.
🔍

Why This Happens

An infinite loop in useEffect occurs when the effect updates a state or value that is also listed in its dependency array. This causes React to run the effect again immediately after each render, repeating endlessly.

For example, if you update a state inside useEffect without limiting when it runs, React keeps re-running the effect because the state change triggers a new render.

javascript
import React, { useState, useEffect } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setCount(count + 1); // Updates state every render
  }, [count]); // Runs whenever 'count' changes

  return <div>Count: {count}</div>;
}
Output
The component keeps increasing count endlessly, causing the browser to freeze or crash.
🔧

The Fix

To fix the infinite loop, avoid updating state inside useEffect without a condition that stops repeated updates. You can also remove unnecessary dependencies or use an empty dependency array [] if the effect should run only once.

In this example, we remove count from dependencies and update state only once on mount.

javascript
import React, { useState, useEffect } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setCount(1); // Set count once on mount
  }, []); // Empty array means run once

  return <div>Count: {count}</div>;
}
Output
Count: 1
🛡️

Prevention

To avoid infinite loops in useEffect:

  • Only include necessary dependencies in the dependency array.
  • Do not update state inside useEffect without conditions that prevent repeated updates.
  • Use React's useCallback or useMemo to memoize functions or values used in dependencies.
  • Use ESLint plugin eslint-plugin-react-hooks to get warnings about missing or extra dependencies.
⚠️

Related Errors

Other common errors related to useEffect dependencies include:

  • Missing dependencies: Effects not updating when expected because dependencies are omitted.
  • Stale closures: Effects using outdated values because dependencies are not tracked properly.
  • Excessive re-renders: Caused by including non-stable objects or functions in dependencies.

Fix these by carefully managing dependencies and using memoization hooks.

Key Takeaways

Only include necessary and stable values in useEffect dependency arrays.
Avoid updating state inside useEffect without conditions to stop repeated updates.
Use empty dependency array [] to run effects only once on mount when appropriate.
Use React hooks like useCallback and useMemo to stabilize dependencies.
Enable eslint-plugin-react-hooks to catch dependency issues early.