Skip to content

useExhaustiveDependencies

诊断类别:lint/correctness/useExhaustiveDependencies

¥Diagnostic Category: lint/correctness/useExhaustiveDependencies

自从:v1.0.0

¥Since: v1.0.0

来源:

¥Sources:

强制在 React hook 中正确指定所有依赖。

¥Enforce all dependencies are correctly specified in a React hook.

此规则是规则 react-hooks/exhaustive-deps 的端口,旨在针对使用 React 的项目。

¥This rule is a port of the rule react-hooks/exhaustive-deps, and it’s meant to target projects that uses React.

如果你的项目不使用 React(或 Preact),则不应使用此规则。

¥If your project doesn’t use React (or Preact), 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

如果你想向规则添加更多钩子,请检查 options

¥If you want to add more hooks to the rule, check the options.

¥Examples

¥Invalid

import { useEffect } from "react";
function component() {
let a = 1;
useEffect(() => {
console.log(a);
}, []);
}
code-block.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]);
}
code-block.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]);
}
code-block.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);
}, []);
}
code-block.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

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

¥Ignoring a specific dependency

有时你可能希望忽略有关特定依赖的诊断,而不禁用该钩子的所有 linting。为此,你可以在括号之间指定特定依赖的名称,如下所示:

¥Sometimes you may wish to ignore a diagnostic about a specific dependency without disabling all linting for that hook. To do so, you may specify the name of a specific dependency between parentheses, like this:

import { useEffect } from "react";
function component() {
let a = 1;
// biome-ignore lint/correctness/useExhaustiveDependencies(a): <explanation>
useEffect(() => {
console.log(a);
}, []);
}

如果你希望忽略多个依赖,可以添加多个注释并为每个注释添加原因。

¥If you wish to ignore multiple dependencies, you can add multiple comments and add a reason for each.

¥Options

允许指定自定义钩子 - 来自库或内部项目 - 应该检查哪些依赖和/或已知哪些具有稳定的返回值。

¥Allows to specify custom hooks - from libraries or internal projects - for which dependencies should be checked and/or which are known to have stable return values.

¥Validating dependencies

对于每个要验证依赖的钩子,你都应指定闭包的索引和要验证的依赖数组的索引。

¥For every hook for which you want the dependencies to be validated, you should specify the index of the closure and the index of the dependencies array to validate against.

¥Example

{
"//": "...",
"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([], () => {});
}

¥Stable results

当已知钩子具有稳定的返回值(其身份在调用过程中不会改变)时,无需在依赖数组中指定该值。例如,React 的 useState 钩子返回的 setter 始终具有相同的标识,因此应省略。

¥When a hook is known to have a stable return value (its identity doesn’t change across invocations), that value doesn’t need to be specified in dependency arrays. For example, setters returned by React’s useState hook always have the same identity and should be omitted as such.

你可以通过以下三种方式之一配置返回稳定结果的自定义钩子:

¥You can configure custom hooks that return stable results in one of three ways:

  • "stableResult": true - 将返回值标记为稳定。可以像这样配置的 React 钩子的一个例子是 useRef()

    ¥"stableResult": true — marks the return value as stable. An example of a React hook that would be configured like this is useRef().

  • "stableResult": [1] - 期望返回值为数组,并将给定的索引标记为稳定。可以像这样配置的 React 钩子的一个例子是 useState()

    ¥"stableResult": [1] — expects the return value to be an array and marks the given index or indices to be stable. An example of a React hook that would be configured like this is useState().

  • "stableResult": 1 - "stableResult": [1] 的简写。

    ¥"stableResult": 1 — shorthand for "stableResult": [1].

¥Example

{
"//": "...",
"options": {
"hooks": [
{ "name": "useDispatch", "stableResult": true }
]
}
}

使用此配置,以下内容有效:

¥With this configuration, the following is valid:

const dispatch = useDispatch();
// No need to list `dispatch` as dependency:
const doAction = useCallback(() => dispatch(someAction()), []);

¥Preact support

此规则识别从 preact/compatpreact/hooks 导入的规则,并应用与 React hooks 相同的规则。

¥This rule recognizes rules imported from preact/compat and preact/hooks and applies the same rules as for React hooks.

¥Related links