useExhaustiveDependencies (since v1.0.0)
Diagnostic Category: lint/correctness/useExhaustiveDependencies
Source: exhaustive-deps
Enforce all dependencies are correctly specified in a React hook.
This rule is a port of the rule react-hooks/exhaustive-deps, and it’s meant to target projects that uses React.
If your project doesn’t use React, you shouldn’t use this rule.
The rule will inspect the following known hooks:
useEffect
useLayoutEffect
useInsertionEffect
useCallback
useMemo
useImperativeHandle
useState
useReducer
useRef
useDebugValue
useDeferredValue
useTransition
If you want to add more hooks to the rule, check the options.
Examples
Section titled ExamplesInvalid
Section titled Invalidimport { useEffect } from "react";
function component() { let a = 1; useEffect(() => { console.log(a); }, []);}
correctness/useExhaustiveDependencies.js:5:5 lint/correctness/useExhaustiveDependencies ━━━━━━━━━━━━
✖ This hook does not specify all of its dependencies: a
3 │ function component() {
4 │ let a = 1;
> 5 │ useEffect(() => {
│ ^^^^^^^^^
6 │ console.log(a);
7 │ }, []);
ℹ This dependency is not specified in the hook dependency list.
4 │ let a = 1;
5 │ useEffect(() => {
> 6 │ console.log(a);
│ ^
7 │ }, []);
8 │ }
ℹ Either include it or remove the dependency array
import { useEffect } from "react";
function component() { let b = 1; useEffect(() => { }, [b]);}
correctness/useExhaustiveDependencies.js:5:5 lint/correctness/useExhaustiveDependencies ━━━━━━━━━━━━
✖ This hook specifies more dependencies than necessary: b
3 │ function component() {
4 │ let b = 1;
> 5 │ useEffect(() => {
│ ^^^^^^^^^
6 │ }, [b]);
7 │ }
ℹ This dependency can be removed from the list.
4 │ let b = 1;
5 │ useEffect(() => {
> 6 │ }, [b]);
│ ^
7 │ }
8 │
import { useEffect, useState } from "react";
function component() { const [name, setName] = useState(); useEffect(() => { console.log(name); setName(""); }, [name, setName]);}
correctness/useExhaustiveDependencies.js:5:5 lint/correctness/useExhaustiveDependencies ━━━━━━━━━━━━
✖ This hook specifies more dependencies than necessary: setName
3 │ function component() {
4 │ const [name, setName] = useState();
> 5 │ useEffect(() => {
│ ^^^^^^^^^
6 │ console.log(name);
7 │ setName("");
ℹ This dependency can be removed from the list.
6 │ console.log(name);
7 │ setName("");
> 8 │ }, [name, setName]);
│ ^^^^^^^
9 │ }
10 │
import { useEffect } from "react";
function component() { let a = 1; const b = a + 1; useEffect(() => { console.log(b); }, []);}
correctness/useExhaustiveDependencies.js:6:5 lint/correctness/useExhaustiveDependencies ━━━━━━━━━━━━
✖ This hook does not specify all of its dependencies: b
4 │ let a = 1;
5 │ const b = a + 1;
> 6 │ useEffect(() => {
│ ^^^^^^^^^
7 │ console.log(b);
8 │ }, []);
ℹ This dependency is not specified in the hook dependency list.
5 │ const b = a + 1;
6 │ useEffect(() => {
> 7 │ console.log(b);
│ ^
8 │ }, []);
9 │ }
ℹ Either include it or remove the dependency array
Valid
Section titled Validimport { useEffect } from "react";
function component() { let a = 1; useEffect(() => { console.log(a); }, [a]);}
import { useEffect } from "react";
function component() { const a = 1; useEffect(() => { console.log(a); });}
import { useEffect, useState } from "react";
function component() { const [name, setName] = useState(); useEffect(() => { console.log(name); setName(""); }, [name]);}
import { useEffect } from "react";let outer = false;function component() { useEffect(() => { outer = true; }, []);}
Options
Section titled OptionsAllows to specify custom hooks - from libraries or internal projects - that can be considered stable.
{ "//": "...", "options": { "hooks": [ { "name": "useLocation", "closureIndex": 0, "dependenciesIndex": 1}, { "name": "useQuery", "closureIndex": 1, "dependenciesIndex": 0} ] }}
Given the previous example, your hooks can be used like this:
function Foo() { const location = useLocation(() => {}, []); const query = useQuery([], () => {});}