useEffect

218 阅读4分钟

使用useEffect

  • 作用:useEffect Hook可以让你在函数组件中执行副作用操作。
  • 如果你熟悉React class的生命周期函数,你可以把useEffectHook看做componentDidMount, componentDidUpdatecomponentWillUnmount这三个函数的组合。也就是在组件加载以后要做的操作
  • 在React组件中有两种常见副作用操作:需要清除的和不需要清除的。

无需清除的useEffect

有时候,我们只想在React更新DOM之后运行一些额外的代码。比如发送网络请求,手动 变更DOM,记录日志,这些都是常见的无需清除的操作。因为我们在执行完这些操作之后, 就可以忽略他们了。让我们对比一下使用class和Hook都是怎么实现这些副作用的。

在React的class组件中,render函数是不应该有任何副作用的。一般来说,在这里执行操作了,我们基本上都希望在React更新DOM之后才执行我们的操作。

这就是为什么在React class中,我们把副作用操作放到componentDidMountcomponentDidUpdate函数中。回到示例中,这是一个React计数器的class组件。它在 React对DOM进行操作之后,立即更新了document的title属性。

useEffect的第一个参数是一个函数,在componenDidMount里的代码,就放在这里面去写。也可以获取真实节点。

需要清除的effect

之前,我们研究如何使用不需要清除的副作用,还有一些副作用是需要清除的。例如订阅外部数据源、计时器等。这种情况下,清除工作是非常重要的,可以防止引起内存泄漏! 在类式组件中,通常会在componentDidMount中设置订阅,并在componentWillUnmount中清除它。componentDidMount和componentWillUnmount之间相互对应。使用生命周期函数迫使我们拆分这些逻辑的,即使这两部分代码都作用于相同的部分。

在useEffec里的销毁操作:

订阅外部数据源,类似于监听的这种。做清除操作的话,在useEffect中添加一个return,返回一个函数,该函数会在组件销毁时执行。

类式组件里的每个生命周期函数只能写一个,多写会报错,函数式的useEffect可以写多个。 uesEffect写多个是为了把有副作用和没有副作用的操作分开。

useEffect做了什么?

通过使用这个Hook,你可以告诉Recat组件需要子啊选然后执行某些擦欧总。Recat会保存你传递的函数(我们将它称之为effect),并且在执行DOM更新之后调用它。子啊这个effect中,我们设置了document的titile属性,不过我们也可以执行数据获取或调用其他命令式的API。

为什么在组件内部调用useEffect?

将useEffect放在组件内部让我们可以直接访问count state变量(或其他props)。我们不需要特殊的API来读取它——他已经保存在函数作用域中。Hook使用了js的闭包机制,而不同js已经停工了解决方案的情况下,还引入特定的Recat API。

useEffect会在每次渲染后都执行吗?

是的。在默认情况下,它在第一次渲染之后和每次更新之后都会执行。你可以更容易接受effect发生在“渲染之后”这种概念,不用再去考虑“挂载”还是“更新”。React保证了每次运行effect同时DOM都已经更新完毕。

如何控制useEffect执行的时机?

注意:

  • useEffect(还有第二个参数(可选参数))
  • 如果没有传入第二个参数,那么组件的初始化和更新都会执行该方法
  • 如果传入了第二个参数(一个空数组),
  • 那么只在初始化调用一次之后不再执行,相当于componentDidMount;
  • 传入第二个参数,只有一个值,该值有变化就执行,传入第二个参数,有多个值的数组,会比较每一个值,有一个不相等就执行。 数组里的[]元素变化,useEffect才会被再次调用,组件更新渲染,数组元素没变化,它并不会重新触发。从而可以理解为useEffect是一个监听函数。