React 带有一个内置的钩子,名为 useEffect。钩子用于函数组件。Class
组件与 useEffect
的比较是方法 componentDidMount
、componentDidUpdate
和 componentWillUnmount
。
useEffect
将在组件渲染时运行,这可能比您想象的要多。感觉过去几周里我已经遇到过十几次这种情况了,所以值得写一篇简短的博文。
import React, { useEffect } from 'react';
function App() {
useEffect(() => {
// Run! Like go get some data from an API.
});
return (
<div>
{/* Do something with data. */}
</div>
);
}
在一个完全隔离的示例中,useEffect
很可能只运行一次。但在一个更复杂的应用程序中,随着 props 的传递等,这肯定不能保证。问题在于,如果您要执行诸如从 API 获取数据之类的操作,您可能会最终进行两次获取,这既没有效率也不必要。
useEffect
接受第二个参数。
诀窍是 第二个参数是一个变量数组,组件将检查该数组以确保在重新渲染之前发生更改。您可以将您想要在此处检查的任何 props 和 state 部分放在这里。
或者,什么也不放
import React, { useEffect } from 'react';
function App() {
useEffect(() => {
// Run! Like go get some data from an API.
}, []);
return (
<div>
{/* Do something with data. */}
</div>
);
}
这将确保 useEffect
只运行一次。
来自文档的说明
如果您使用此优化,请确保该数组包含来自组件范围(例如 props 和 state)的所有随着时间推移而发生变化且被效果使用的值。否则,您的代码将引用来自先前渲染的过时值。
或者,简单地使用 eslint-plugin-react-hooks 来确保您的钩子及其使用方法!
https://npmjs.net.cn/package/eslint-plugin-react-hooks
这看起来很有用,但我认为它不能解决问题。
这绝对正确,但如果理解错误、使用错误或过度使用,就可能很危险。
Dan Abramov 写了一篇关于 useEffect 的来龙去脉的精彩(但很长)的解释,它让我真正理解了它。
https://overreacted.io/a-complete-guide-to-useeffect/
两件事,根据设计,React 将在 props 或 state 发生更改时渲染。由于
useEffect
在每次渲染时都会运行,如果您在其中更改了 state 或 props,您将不可避免地陷入无限循环。此外,要获得componentDidMount
,您运行一些代码,然后将一个空数组作为第二个参数传递给useEffect
。要只运行一次componentWillUnmount
,您需要从useEffect
返回一个清理函数,并将一个空数组也作为第二个参数传递。我一直在将一些代码库转换为 Hooks,这变得非常引人入胜。
useEffect
的一个问题是它很容易搞砸,我已经搞砸了很多次了。但除此之外,它解决了很多问题,作为奖励,它还很简单。这种方法的问题是,如果您依赖任何 props 或 state,它会触发警告(由于
react-hooks/exhaustive-deps
eslint 规则)。最好在您的代码库中定义一个自定义 Hook
并导入并使用它。