Effect Hook 是什么
可以将 Effect Hook
看做是 class 组件中 componentDidMount
、componentDidUpdate
、componentWillUnmount
三个函数的组合。
Effect Hook 解决什么问题
Effect Hook
可以解决 class
组件同一生命周期函数经常包含不相关的逻辑,但又把相关逻辑分离到了不同生命周期的问题。Effect Hook
会在每次渲染后(挂载或更新,在 class 组件中,这两个过程是两个不同个生命周期)被执行,我们可以在 Effect Hook
中执行副作用操作,如数据获取、dom 更新、事件的监听和清除、定时器的设定和清理等,从而将相关逻辑聚集在同一个地方。
与 componentDidMount
或 componentDidUpdate
不同,使用 useEffect
调度的 effect
(传给 useEffect 的函数叫做 effect) 不会阻塞浏览器更新屏幕,这让我们的应用看起来响应更快。
effect 的清除机制
当我们在 effect 中添加了监听、定时器等需要清理的资源时,可以给 effect
返回一个清理函数,将清理操作放到清理函数中。React 会在组件卸载、和下次执行对应 effect 时,执行此清理函数。
1 | import React, { useState, useEffect } from 'react'; |
当 effect 内容不需要清理时,则无需返回函数。
1 | useEffect(() => { |
注意
逻辑分离
可以使用多个 effect,将不同的逻辑分离开。React 会按照 effect 声明的顺序依次调用组件中的每一个 effect。
1 | function FriendStatusWithCounter(props) { |
控制渲染频率(性能)
可以通过给 useEffect 传递第二个参数(数组类型)来控制组件的渲染。
下面示例中,将 count 作为数组参数传递给 useEffect 时,react 只有当 count 的值发生变化时,才会调用 effect 函数和清理函数。
1 | useEffect(() => { |
当 useEffect 的第二个参数的数组中有多个元素时,只有当所有元素都没有发生变化时,react 才会忽略 effect的执行。
当 useEffect 的第二个参数的数组为空时,这就告诉 React 你的 effect 不依赖于 props 或 state 中的任何值,所以它永远都不需要重复执行。
语法校验
官方推荐启用 eslint-plugin-react-hooks
中的 exhaustive-deps
规则。此规则会在添加错误依赖时发出警告并给出修复建议