react-hooks/exhaustive-effect-dependencies
Require the dependency array of an effect to match what the effect reads
Also called react_hooks/exhaustive-effect-dependencies, react/exhaustive-effect-dependencies
An effect runs again only when something in its dependency array changes. If the effect reads a value that's missing from the array, it doesn't run when that value changes and keeps working with the old one. If the array lists a value the effect never reads, the effect runs more often than it needs to.
This check comes from the React Compiler, which works out what each effect in a component or hook depends on and compares that with your array.
In .ts and .tsx files, the report comes with a suggestion that rewrites the array, which your editor can apply.
With an ESLint config the rule reports nothing, because eslint-plugin-react-hooks leaves this compiler check switched off. Use react-hooks/exhaustive-deps there.
Configure#
Off by default. To turn it on:
[lint.rules]
"react-hooks/exhaustive-effect-dependencies" = "error" # or "warn"Examples#
import { useEffect } from "react";
function Room({ roomId }) {
useEffect(() => {
connect(roomIdError: Found missing effect dependenciesMissing dependencies can cause an effect to fire less often than it should.);
}, []); // stays in the first room
}import { useEffect } from "react";
function Room({ roomId, theme }) {
useEffect(() => {
connect(roomId);
}, [roomId, themeError: Found extra effect dependenciesExtra dependencies can cause an effect to fire more often than it should, resulting in performance problems such as excessive renders and side effects.]); // reconnects when the theme changes
}import { useEffect } from "react";
function Room({ roomId }) {
useEffect(() => {
connect(roomId);
}, [roomId]);
}