先来背书:三种useEffect的执行时机
- 不加依赖数组:
useEffect(() => { // do something });
在componentDidMount(第一次render渲染执行完成)、componentDidUpdate(props、state等发生变化触发重渲染)时执行
-
加空依赖数组:
useEffect(() => { // do something }, []);
只在componentDidMount时执行
-
加非空依赖数组:
useEffect(() => { // do something }, [dep1, dep2, dep3]);
在componentDidMount、依赖数组中的变量发生变化时执行
好了,如果不想理解为什么,只想背api的看到这里可以关掉文章了:)
----------------------------------------------------我是分割线---------------------------------------------------------
所以这奇奇怪怪的执行时机真的只能靠死记硬背的吗?当然不是。我们来看官方对useEffect的解释是什么:
The Effect Hook lets you perform side effects in function components.
useEffect钩子让你能在函数组件中执行副作用。
啥叫副作用?就是在函数组件正常的渲染程序,因某些变化引起的额外程序。这个变化就是props、state等发生变化导致的重新渲染,也就是componentDidUpdate钩子。
但如果就只是这么简单的话,useEffect没有第二个参数:依赖数组的话,useEffect就只是简简单单componentDidMount和componentDidUpdate的结合体。这就是不加依赖数组的useEffect。
官方对useEffect第二个参数的解释:
You can tell React to skip applying an effect if certain values haven’t changed between re-renders.
你可以告诉React,如果某些特定值在两次重渲染之间没有发生变化,就跳过副作用。
这里的 “某些特定值”就是指你传入第二个参数,依赖数组中的变量们的值。第二个参数其实就是在componentDidUpdate触发的基础上,加上了一层过滤:如果这次Update并不是由依赖数组里的哪个变量引起的,就不用触发。
然后我们再来看:
- 加空依赖数组:全部componentDidUpdate都过滤掉了,只剩下componentDidMount
- 加非空依赖数组:过滤掉部分componentDidUpdate,只剩下由依赖数组中变量变化导致的componentDidUpdate(准确点说应该是componentDidUpdate,且依赖数组中值变化)
就写这么多~
参考官方文档: