本文将讲解useCallback的源码实现。useCallback是也一个非常简单的钩子,其实现比useMemo还要简单。
Mount阶段
在这个阶段中,主要完成hook实例的创建,以及缓存当前的callback及其依赖列表。
function mountCallback<T>(callback: T, deps: Array<mixed> | void | null): T {
// 创建一个hook实例
const hook = mountWorkInProgressHook();
const nextDeps = deps === undefined ? null : deps;
// 缓存当前的callback及其依赖列表
hook.memoizedState = [callback, nextDeps];
return callback;
}
其他阶段
Update和Rerender阶段useCallback的处理逻辑都是一样的。
- 进行依赖比较
- 如果新依赖与旧依赖一致(其比较方式与useMemo一致,都采用的是
Object.is比较方法),返回原callback - 如果不一致,返回新的
callback,并缓存新callback以及新依赖列表。
function updateCallback<T>(callback: T, deps: Array<mixed> | void | null): T {
const hook = updateWorkInProgressHook();
const nextDeps = deps === undefined ? null : deps;
const prevState = hook.memoizedState;
if (prevState !== null) {
if (nextDeps !== null) {
const prevDeps: Array<mixed> | null = prevState[1];
// 比较新旧依赖列表
if (areHookInputsEqual(nextDeps, prevDeps)) {
return prevState[0];
}
}
}
hook.memoizedState = [callback, nextDeps];
return callback;
}