副作用

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

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

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

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

…
和外部变量的交互

使用 useEffect 就是对副作用操作

useEffect(回调函数, 依赖项)

渲染后执行

useEffect 相当在类组件中是使用 componetDidMount 和 componentDidUpdate 这两个生命周期钩子中做了一个简单合拼的操作。
会在真实 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 时,相当于类组件设置了 componentDidMount、componentDidUpdate、componentWillUnmount(设置了清理 effect 的话)
依赖项为 [] 空数组时,effect 只会执行一次 componentDidMount、componentWillUnmount

  • 如果在这样设置后,在 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. }