副作用

纯函数是没有副作用,相同的输入会有相同的输出。
而副作用可以概括为

  1. 引用外部变量
  2. 调用外部函数

React 中的副作用是针对于组件渲染时,不使用到的变量和操作就是副作用。

  1. 修改 DOM
  2. 修改全局变量
  3. ajax
  4. 计时器
  5. 存储相关


和外部变量的交互

使用 useEffect 就是对副作用操作

useEffect(回调函数, 依赖项)

渲染后执行

useEffect 相当在类组件中是使用 componetDidMountcomponentDidUpdate 这两个生命周期钩子中做了一个简单合拼的操作。
会在真实 DOM 构建之后(渲染后)会执行 useEffect 的回调函数,其执行方式是异步的。

如果在 DOM 构建之前可以使用 useLayoutEffect

清理 effect

回调函数可以返回一个函数,用于清除副作用的回调。相当于类组件使用 componentWillUnmount

  1. useEffect(() => {
  2. return () => {
  3. // 清理 effect
  4. }
  5. })

清理 effect 的回调执行会在第首次渲染后(componentDidUpdate)的 effect 回调执行前执行。即 componentDidMount 不会执行清理 effect,之后每次执行 useEffect 的回调(componentDidUpdate)时先执行清理 effect。
当组件要被销毁时(componentWillUnmount)也会被执行清理 effect。

依赖项

当依赖项为 undefined 时,相当于类组件设置了 componentDidMountcomponentDidUpdatecomponentWillUnmount(设置了清理 effect 的话)
依赖项为 [] 空数组时,effect 只会执行一次 componentDidMountcomponentWillUnmount

  • 如果在这样设置后,在 effect 中 setState 时只会拿到 useState 的默认值
  • 这时可以使用 setState((val)=>val++) 回调函数的方式来设置

当依赖项有值时,只会侦听依赖项改变时才会触发 effect

关注点分离使用自定义 hooks

  1. const useCount = (param) => {
  2. const [count, setCount] = useState(param);
  3. useEffect(() => {
  4. setCount((count) => count++);
  5. }, []);
  6. return [count, setCount];
  7. }