热搜:fiddler git ip ios 代理
历史搜索

解密使用useMount和useUnmount的重要性

游客2024-08-03 10:30:02
目录文章目录
  1. React Hooks 的执行顺序
  2. 原理分析
  3. useMount 和 useUnmount

解密使用useMount和useUnmount的重要性 1

通过结果可以得到,先执行 useMemo,接着执行 useLayoutEffect 的 side effect cleanup,useEffect 的 side effect cleanup,等到 React update DOM and Refs 执行后,再执行 useLayoutEffectuseEffect

通过这个例子,基本上弄清楚 useEffect 的执行顺序,由此分析使用 useEffect 模拟生命周期方法不当会导致什么问题。

  • 对于生命周期挂载方法,使用 useEffect 模拟 mount 如下:
    useEffect(() => {
      // do something
    }, []);
    

    只有当useEffect的 deps 参数是空数组时,该用法才等同于mount方法

  • 对于组件销毁的生命周期方法,使用useEffect模拟unmount如下:
    useEffect(() => {
      return () => {
        // do something
      }
    }, []);
    

useMount 和 useUnmount

前面的问题根本原因是 useEffect 与 Lifecycle Methods 需要解耦。如果 useEffectdeps 参数不是空数组,那么当前的 useEffect 不等同 mount 方法,就会造成意外的结果

社区里提供专门的 ahooks 解决这个问题,这个第三方库中有两个重要方法,分别是 useMount 和 useUnmount

useMount 的实现如下:

// useMount.ts

import { useEffect } from 'react'

const useMount = (fn: () => void) => {
  if (!isFunction(fn)) {
    console.error(`useMount: parameter `fn` expected to be a function, but got "${typeof fn}".`)
  }

  useEffect(() => {
    fn?.()
  }, [])
}

export default useMount

useUnmount 的实现如下:

// useUnMount.ts

import { useEffect, useRef } from 'react'

export default function useUnmount(fn: () => void): void {
  if (!isFunction(fn)) {
   console.error(`useUnmount: parameter `fn` expected to be a function, but got "${typeof fn}".`)
  }

  const ref = useRef(fn)

  useEffect(
    (): (() => void) => (): void => {
      ref.current?.()
    },
    []
  )
}

function isFunction(fn: unknown): fn is Function {
  return typeof fn === 'function'
}

在项目中这样使用useMountuseUnMount

const App = () => {
  useMount(() => {
    // ...
  })

  useUnMount(() => {
    // ...
  })

  return <></>
}

使用useMountuseUnmount就不用考虑传入的依赖,实现useEffect与 Lifecycle Methods 解耦

以上就是关于我们为什么需要 useMount 和 useUnmount 的详细内容,更多请关注www.mimiwuqi.com的其它相关文章!

标签:React