It’s surprisingly easy to create infinite loops in React.
If you’ve encountered an infinite loop in React, it’s almost certain that you’ve added code inside an effect hook without specifying a dependency. Unfortunately, React doesn’t tell you that you’re doing anything wrong.
Here’s a simple example in which you update and render a counter.
import { useEffect, useState } from "react";
export const MyInfiniteLoop = () => {
const [count, setCount] = useState(0);
useEffect(() => setCount(count + 1));
return <div>Count: {count}</div>;
};
In this case, here’s what happens:
useEffect()
runs.count
is incremented by 1
. This triggers a re-render. (Go to #1.)The way to get around this is to specify an array of dependencies to the effect hook. By default, there are no dependencies, which means it will run every time the component renders.
You can instead tell the hook that it has no dependencies, and so it will only render a single time.
import { useEffect, useState } from "react";
export const MyInfiniteLoop = () => {
const [count, setCount] = useState(0);
// Use an empty array as the second arg to specify no dependencies
useEffect(() => setCount(count + 1), []);
return <div>Count: {count}</div>;
};
If you’re using eslint, as is a common practice in modern JavaScript projects, then you can make use of the eslint-plugin-react-hooks plugin, which will throw warnings when there is a risk for more renders than intended.