useDeepCompareEffect
作用
useDeepCompareEffect
会在依赖变化时执行副作用,与 useEffect
不同的是,useDeepCompareEffect
会对依赖进行深度比较,而不是引用比较。
原理
通过
useRef
缓存依赖的值,然后通过useEffect
监听依赖的变化,当依赖变化时,通过isEqual
比较依赖的值是否相等,如果不相等,则执行副作用
源码
ts
import { useEffect } from 'react'
import { createDeepCompareEffect } from '../createDeepCompareEffect'
// 创建一个深度比较的 useEffect
export default createDeepCompareEffect(useEffect)
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)