
useEffect 钩子自 16.8 版推出以来,已成为 中的一项流行功能。它使开发人员能够在功能组件中执行副作用,如、更新 DOM 和订阅事件。
不过, useEffect 钩子的使用有时会很棘手。开发人员遇到的一个常见错误是 “React Hook useEffect has a missing dependency. Either include it or remove the dependency array” 的错误。
在本文中,我们将讨论导致该错误的原因,并提供如何修复该错误的各种解决方案。
当 useEffect 钩子的依赖关系数组不完整或丢失时,就会出现 “React Hook useEffect has a missing dependency”(React 钩子使用效果缺少依赖关系)错误。
依赖关系数组是 useEffect 钩子中的第二个参数,用于指定效果所依赖的变量。这意味着当依赖关系数组中指定的变量值发生变化时,将重新执行效果。
如果效果所依赖的变量未包含在依赖关系数组中,那么当变量值发生变化时,效果可能不会被重新执行。这可能会导致应用程序出现意外行为和错误。
此错误不是 React 错误,而是 ESLint 错误。 专门为 React 提供了一个插件,其中包含一套规则,旨在帮助开发人员编写更好的 React 代码。其中一个规则是 "react-hooks/exhaustive-deps" 规则,它可以检测 “React Hook useEffect has a missing dependency” 错误。
举例来说,我们来看一个具有计数状态的功能组件。每当计数状态发生变化时,该组件也要向控制台记录一条包含 count 值的消息:
import { useState, useEffect } from 'react';
const App = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`You clicked ${count} times`);
}, []);
return (
<div>
<h1>Hello World</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default App;
在上例中,您有一个使用 useState 和 useEffect 挂钩的功能组件。每当 count 状态变量的值发生变化时, useEffect 钩子就会记录一条信息。
但请注意,count 变量并没有列在 useEffect 钩子的第二个参数数组(依赖数组)中。这将触发 “React Hook useEffect has a missing dependency” 错误。

React 钩子 useEffect 有一条缺少依赖关系的错误信息
根据您希望使用的 *** ,可以用不同的方式来修复这个错误。以下是各种 *** 。
解决这一错误的直接 *** 是将 useEffect 钩子中使用的所有依赖关系都加入依赖关系数组。那么您可能会问,我如何知道依赖关系呢?
要识别缺失的依赖关系,您需要查看 useEffect 钩子中使用的变量或值。如果这些变量或值会随着时间的推移而发生变化,那么它们就应该包含在依赖关系数组中。
例如,在前面提供的代码片段中, useEffect 钩子内部使用了 count 变量,但它并没有包含在依赖关系数组中。这意味着如果 count 变量发生变化,useEffect 钩子将不会被重新执行,组件可能会出现过时数据或其他问题。
要解决这个错误,我们可以将 count 变量添加到依赖关系数组中,就像下面这样:
import { useState, useEffect } from 'react';
const App = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`You clicked ${count} times`);
}, [count]);
return (
<div>
<h1>Hello World</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default App;
通过将 count 变量添加到依赖关系数组,我们可以告诉 React,只要 count 变量发生变化,就会重新执行 useEffect 钩子。
这将确保组件始终拥有最新数据,并避免出现 “React Hook useEffect has a missing dependency” 的错误。
如果您有多个依赖项,请将它们添加到依赖项数组中,并用逗号将它们分开:
import { useState, useEffect } from 'react';
const App = () => {
const [firstName, setFirstName] = useState('');
const [lastName, setlastName] = useState('');
const [fullName, setFullName] = useState('');
useEffect(() => {
setFullName(`${firstName} ${lastName}`);
}, [firstName, lastName]);
const handleFirstNameChange = (event) => {
setFirstName(event.target.value);
};
const handleLastNameChange = (event) => {
setLastName(event.target.value);
};
return (
<div>
<label>
First Name:
<input type="text" value={firstName} onChange={handleFirstNameChange} />
</label>
<label>
Last Name:
<input type="text" value={lastName} onChange={handleLastNameChange} />
</label>
<p>Full Name: {fullName}</p>
</div>
);
};
export default App;
在使用对象和数组时,仅将它们添加到依赖数组中是不够的,还需要将它们 memoize 或移动到 useEffect 钩子中或组件外部,以避免不必要的重新呈现。
这是因为在 JavaScript 中,对象和数组是通过引用进行比较的,每次都指向内存中的不同位置,因此每次呈现时其值都会改变,从而导致无限的重新呈现循环。
下面是一个导致错误的示例:
import { useState, useEffect } from 'react';
const App = () => {
const [user, setUser] = useState({});
// ️this will change on every render
let newUser = { name: 'Jane', age: 28 };
useEffect(() => {
setUser(newUser);
}, [newUser]);
return (
<div>
<h1>Hello World</h1>
</div>
);
};
export default App;
您可以通过将对象移入 useEffect 钩子或将其移出组件来解决这个错误:
import { useState, useEffect } from 'react';
const App = () => {
const [user, setUser] = useState({});
useEffect(() => {
let newUser = { name: 'Jane', age: 28 };
setUser(newUser);
}, []);
return (
<div>
<h1>Hello World</h1>
</div>
);
};
export default App;
解决这一问题的更好 *** 是使用备忘录化钩子,如对对象使用 useMemo,对函数使用 useCallback。这将有助于在组件和依赖关系数组中保留对象或函数。
注:memoization 钩子是一组钩子,可让您缓存昂贵的计算结果,避免不必要的重新计算。
当您使用 useMemo 钩子对对象进行记忆化处理时,您的代码就会变成这样:
import { useState, useEffect, useMemo } from 'react';
const App = () => {
const [user, setUser] = useState({});
const newUser = useMemo(() => {
return { name: 'John', age: 30 };
}, []);
useEffect(() => {
setUser(newUser);
}, [newUser]);
return (
<div>
<h1>Hello World</h1>
</div>
);
};
export default App;
同样,在使用函数时,可以使用 useCallback 钩子。
“React Hook useEffect has a missing dependency” 错误是一个 ESLint 警告错误,这意味着我们可以禁用该规则,这样它就不会抛出该错误。并不建议在所有情况下都采用这种 *** ,但如果您确定缺少的依赖关系不是一个问题,这种 *** 可以快速解决问题。
可以在依赖关系数组行前添加以下注释。
// eslint-disable-next-line react-hooks/exhaustive-deps
下面就是一个例子:
useEffect(() => {
console.log(`You clicked ${count} times`);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
需要注意的是,如果不小心禁用 ESLint 规则,将来可能会导致其他问题。请确保在禁用规则前彻底了解其后果,并尽可能考虑其他解决方案。
“React Hook useEffect has a missing dependency” 错误是 React 开发人员在使用 useEffect 挂钩时面临的常见问题。
在修复该错误时,重要的是要考虑针对特定用例的更佳 *** 。一般来说,更好避免禁用导致该错误的 ESLint 规则,因为这会在将来导致其他问题。相反,可以尝试在依赖关系数组中加入缺失的依赖关系,或使用正确的 memoization 钩子来解决这个问题。
现在轮到你了: 您遇到过这个问题吗?你是如何解决的?您还使用过本文未涉及的其他 *** 吗?请在评论中告诉我们!
谁在尝试访问某些网站时没有遇到过更新Java的请求? 虽然许多人通过交互式网站功能熟悉Java,但用户可能不太熟悉JavaScript——或者,实际上,他们可能错误地认为两者是相同的。 在本文中,我们将讨论JavaScript 是什么以及Java和JavaScript之间的区别。然后我们将概...
宝塔面板提供丰富的软件以一键安装,这让服务器环境搭建提供不少的便利性,站长可以根据实际需求快速编译安装以实现不同的功能需求。 软件管理,主要是宝塔提供的一些面板扩展插件。 Nginx Nginx是一个高性能的HTTP和反向代理服务器,具有轻量级、占用内存小,并发能力强等优势。 w...
宝塔面板的计划任务,主要用于安排和管理需要定时执行的任务,如备份、内存清理等。其实对于大部分站长来说,主要使用该板块的备份网站、备份数据库及释放内存的三个定时任务计划。 Shell脚本的添加 输入任务名称,选择执行周期,输入执行的脚本内容。 注意事项: 输入脚本内容...
由于市场上有各种可用的数据库,用户经常会就MongoDB与MySQL进行辩论,以找出更好的选择。 使用MySQL等关系数据库的组织在根据不断变化的需求管理和存储数据时可能会面临一定的困难。同时,新公司想知道选择什么数据库,这样他们就不会在开发过程中遇到问题。 同时,构建金融应用程序的开发人员...
您的网络服务器软件会影响您网站的整体性能和加载时间。出于这个原因,选择最适合您需求的Web服务器对于您的网站的成功至关重要。然而,有这么多可用的选项,要知道安装和使用哪一个可能具有挑战性。 在本指南中,我们将回顾八款适用于Windows和Linux的最佳Web服务器。 什么是Web服...
数据库本质上是任何软件的支柱。随着市场上的多个数据库以及的日益普及,许多开发人员和企业都有一个共同的担忧:您如何选择合适的? 在本文中,我们将讨论最流行的两个开源数据库——MariaDB和PostgreSQL。 虽然PostgreSQL已经存在了20年并且在稳定性方面非常出色,但MariaD...