Effect
useUpdateEffect
用于更新 Effect Hook
用法
用法等同于 useEffect,但不同的是,会忽略首次执行,只在依赖更新时执行。
effectCount: 0
updateEffectCount: 0
源码
import { useEffect } from 'react';
import { createUpdateEffect } from '../createUpdateEffect';
export default createUpdateEffect(useEffect);import { useRef } from 'react';
import type { useEffect, useLayoutEffect } from 'react';
type EffectHookType = typeof useEffect | typeof useLayoutEffect;
export const createUpdateEffect: (hook: EffectHookType) => EffectHookType =
(hook) => (effect, deps) => {
const isMounted = useRef(false);
// for react-refresh
hook(() => {
return () => {
isMounted.current = false;
};
}, []);
hook(() => {
if (!isMounted.current) {
isMounted.current = true;
} else {
return effect();
}
}, deps);
};
export default createUpdateEffect;解读
首先,调用 createUpdateEffect 函数,传入 useEffect 函数。createUpdateEffect 函数接收一个函数作为参数,返回一个新函数。这样封装的目的是为了支持 useLayoutEffect 的用法。ahooks 中有很多类似的这种封装,因为需要同时支持 useEffect 和 useLayoutEffect 的用法。
直接把源码中的参数 hook 替换成 useEffect,再来看看实际的代码:
export const useUpdateEffect = (effect, deps) => {
// 1. 使用 useRef 定义一个 ref 对象,用于记录组件是否已经挂载
const isMounted = useRef(false)
// 2. 使用 useEffect 监听组件的卸载,在组件卸载时,将 isMounted 的值设置为 false
useEffect(() => {
return () => {
isMounted.current = false
}
}, [])
// 3. 使用 useEffect 监听依赖的更新
// 因为 useEffect 会在组件挂载时执行一次,但是由于 isMounted 的初始值为 false,所以会跳过这次 effect 的执行
// 后续依赖更新时,才会执行 effect
useEffect(() => {
if (!isMounted.current) {
isMounted.current = true
} else {
return effect()
}
}, deps)
}Last updated on