React的useCallback和useMemo缓存大小是多少?useCallback源码分析及验证
React useCallback 和 useMemo 的缓存大小是多少?原因是什么?
结论先行
useCallback 和 useMemo 的缓存大小都是 1 —— 它们只会缓存最近的一次回调函数或计算结果,不会保留任何历史缓存版本。
针对 useCallback 的详细分析(结合你提供的源码)
你的理解完全正确!我们可以从你贴出的React源码实现来验证这一点:
mount 阶段(首次渲染)
function mountCallback<T>(callback: T, deps: Array<mixed> | void | null): T { const hook = mountWorkInProgressHook(); const nextDeps = deps === undefined ? null : deps; hook.memoizedState = [callback, nextDeps]; return callback; }
首次渲染时,React会创建一个hook对象,把传入的回调函数和依赖数组以数组形式存在hook.memoizedState里——这里只存储了当前这一组数据,没有额外的缓存空间。
update 阶段(重新渲染)
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; }
重新渲染时,React会对比新老依赖数组:
- 如果依赖没变化,直接返回
hook.memoizedState里存储的旧回调(也就是上一次缓存的唯一值); - 如果依赖变化了,就用新的回调和依赖覆盖掉
hook.memoizedState里的内容——这里始终只保留最新的一组数据,没有历史版本的存储逻辑。
正因为每次更新只会替换缓存的内容,不会追加,所以useCallback的缓存大小固定为1。
关于 useMemo 的补充
useMemo的实现逻辑和useCallback几乎完全一致,只是它缓存的是计算结果而非回调函数:
- mount阶段会把计算结果和依赖存在
hook.memoizedState; - update阶段对比依赖,没变化返回缓存的结果,变化了重新计算并更新缓存。
同样,它也只会保留最近的一次计算结果,缓存大小也是1。
内容的提问来源于stack exchange,提问作者Yos
相关产品推荐
相关产品推荐

