Skip to content

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.

import { 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
  
import { 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;
}, []);
}

Allows 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([], () => {});
}