前言
useMemo和useCallback是成对的,在使用上也很相像;根据不同场景使用不同的hook,来做优化。
源码解析
const cachedValue = useMemo(calculateValue, dependencies)
mount阶段
按照常规流程,调用HooksDispatcherOnMountInDEV.useMemo的方法,前置check检查方法,核心方法mountMemo;
首先调用mountWorkInProgressHook方法,
const hook = {
memoizedState: null,
baseState: null,
baseQueue: null,
queue: null,
next: null
};
fiber.memoizedState = hook;
mountMemo的核心代码
const nextValue = calculateValue();
hook.memoizedState = [nextValue, dependencies];
return nextValue;
相比于useCallback,useMemo多了一些逻辑函数执行,然后将函数的返回值保存和返回,
mountMemo的逻辑就是创建hook对象,然后将函数执行,将执行的返回值保存下来并返回返回值。
update阶段
按照常规流程,调用HooksDispatcherOnUpdateInDEV.useMemo 的方法,前置check检查方法,核心方法updateMemo;
调用updateWorkInProgressHook方法,就是更新hook对象;
将hook.memoizedState获取的值和当前传入的值进行对比,
if(Object.is(hook.memoizedState[1],dependencies)){
return hook.memoizedState[0]
}
const nextValue = calculateValue();
hook.memoizedState = [nextValue, dependencies];
return nextValue;
更新阶段就是判断依赖是否一致,如果一致就返回之前的值,否则就是重新执行函数,将值缓存并返回执行的值。
总结
useMemo相比于useCallback多了一步函数执行逻辑,缓存执行的结果,其他的逻辑和useCallback都一样。
补充
useCallback和useMemo的区别;
相同点:useCallback和useMemo都是用于用户缓存手段;
不同点:useMemo会执行函数,缓存返回结果,useCallback会缓存函数。