Skip to content

useDeepCompareLayoutEffect

作用

useDeepCompareLayoutEffect 会在依赖变化时执行副作用,与 useLayoutEffect 不同的是,useDeepCompareLayoutEffect 会对依赖进行深度比较,而不是引用比较。

原理

通过useRef缓存依赖的值,然后通过useEffect监听依赖的变化,当依赖变化时,通过isEqual比较依赖的值是否相等,如果不相等,则执行副作用

源码

ts
import { useLayoutEffect } from 'react'
import { createDeepCompareEffect } from '../createDeepCompareEffect'

export default createDeepCompareEffect(useLayoutEffect)

createDeepCompareEffect

ts
import { useRef } from 'react'
import type { DependencyList, useEffect, useLayoutEffect } from 'react'
// 深度比较的工具方法
import { depsEqual } from '../utils/depsEqual'

type EffectHookType = typeof useEffect | typeof useLayoutEffect
type CreateUpdateEffect = (hook: EffectHookType) => EffectHookType

export const createDeepCompareEffect: CreateUpdateEffect = (hook) => (effect, deps) => {
  // 保存上一次的依赖
  const ref = useRef<DependencyList>()
  // 保存一个标识
  const signalRef = useRef<number>(0)

  // 如果依赖变化了,则更新标识
  if (deps === undefined || !depsEqual(deps, ref.current)) {
    ref.current = deps
    signalRef.current += 1
  }

  // 标识变化时,执行副作用
  hook(effect, [signalRef.current])
}

depsEqual

ts
import type { DependencyList } from 'react'
import { isEqual } from 'lodash-es'

// 比较两个依赖是否相等
export const depsEqual = (aDeps: DependencyList = [], bDeps: DependencyList = []) =>
  isEqual(aDeps, bDeps)

如有转载或 CV 的请标注本站原文地址