什么是 useEffect hook 以及如何使用它?
内容
useEffect hook 介绍。
哪些参数传递给 useEffect 钩子?
将函数作为依赖项传递
参考
内容
这是我的 React Hooks 系列的第三篇文章。如果你还没看过前两篇,请点击下面的链接查看。
useEffect hook 介绍。
钩子是一种函数,它使您无需编写 ES6 类即可使用状态和其他 React 功能。useEffect
钩子是 React 钩子 API 的一部分。如果您熟悉 React 生命周期,那么useEffect
钩子相当于生命周期方法componentDidMount
,componentDidUpdate
并且componentWillUnmount
是两者的结合。事实上,根据React 文档中关于钩子的内容,useEffect
钩子的开发是为了解决 ES6 类组件的生命周期方法所带来的一些挑战。由于这篇文章是关于什么是 effect hook 以及如何使用它,我不会深入讨论它被开发的原因。你可以在这里查看。
在 React 函数式组件中,我们执行side effects
诸如从 API 获取数据或在钩子内手动更新 DOM 之类的操作useEffect
。
哪些参数传递给 useEffect 钩子?
useEffect
是一个接受两个参数的函数。传递给它的第一个参数useEffect
是一个名为 的函数effect
(你可以猜到这个钩子被命名为useEffect
),第二个参数(可选)是一个依赖项数组。下面是它的使用示例。
import React, { useEffect } from "react";
import { render } from "react-dom";
const App = props => {
useEffect(() => {
console.log("Effect has been called");
}); //Second argument to useEffect has been omitted
return <h1> Hello world! </h1>;
};
const root = document.getElementById("root");
render(<App />, root);
useEffect 的第一个参数
第一个参数,称为effect
,是一个函数,它返回一个函数(称为cleanup
)或undefined
。effect
在组件挂载时(第一次渲染时)执行,并且它是否在后续更新中执行由作为第二个参数传递的依赖项数组决定。
效果参数的返回值
在上一节中,我们提到 的第一个参数useEffect
是一个名为 的函数effect
。effect
它不接受任何参数,并且必须返回一个函数或 undefined。如果它返回一个函数,则返回的函数称为cleanup
。cleanup
会在调用之前执行(以清除上次渲染的效果)。如果您对为什么以及何时需要清除感到好奇,请查看React 文档effect
中的解释。由于返回一个函数或 undefined,因此经常会看到没有 的情况。effect
effects
cleanup
useEffect 的第二个参数
的第二个参数是依赖useEffect
项数组。如果要控制在安装组件后何时执行,请传递依赖项数组作为第二个参数。这些值在外部定义,但在内部使用,例如:effect
dependencies
useEffect
useEffect
function App(){
const[state, setState] = useState(0);
// state is defined here
useEffect(() => {
console.log(state);
//value of state is used here therefore must be passed as a dependency
}, [state])
}
React 会比较依赖项的当前值和上一次渲染时的值。如果它们不同,effect
则会调用。
此参数是可选的。如果省略,effect
则会在每次渲染后执行。如果只想effect
在第一次渲染时执行,可以传递一个空数组。
useEffect(() => {
console.log("Effect has been called");
}, []) // Empty array as dependency, useEffect is invoked once
依赖项可以是 state 或 props。需要注意的是,任何在useEffect
组件内部外部定义的值,如果要在组件内部使用,都必须作为依赖项传递useEffect
。如下所示。
function App(props) {
const [count, setCount] = React.useState(1);
// count and setCount are defined inside component(App) but outside useEffect
useEffect(() => {
//count is being used inside useEffect. Therefore must be passed as dependency.
console.log(count);
}, [count])
}
将函数作为依赖项传递
你可能会想,如果在外部定义一个函数useEffect
,并在内部调用它effect
,是否需要将其作为依赖项传递?
例如:
function App(props){
const [data, setData] = useState(null);
const fetchData = () => {
//fetch some data
}
useEffect(() => {
fetchData(); //Invoked inside useEffect
}, [fetchData])
}
不建议在 外部定义函数并在 内部调用它effect
。上述情况会导致fetchData
每次渲染时都会调用该函数,因为传递的依赖项是函数,而函数是对象。React 会比较上fetchData
一次渲染和当前渲染,如果两者不同,则会触发 的调用effect
。
根据React 文档中关于 useEffect hook 的描述,
记住效果外部的函数使用了哪些 props 或 state 是很困难的。这就是为什么你通常需要在效果内部声明它所需的函数。这样就很容易看出该效果依赖于组件作用域中的哪些值:
您还可以将函数移动到效果内部,这样它就不需要位于其依赖列表中。
感谢您阅读到这里。本文是对 Hook 的简要介绍useEffect
。关于 Hook,还有很多内容useEffect
我尚未在本文中提及。您需要一些时间来熟悉它。如果您想深入了解 Hook useEffect
,请查看以下参考资料。如果您觉得本文有用,请在Twitter上分享。其他人也可能会觉得它有用。如果您发现任何技术上不准确的地方,请随时在下方评论。