第六章:useDeferredValue源码解析

202 阅读2分钟

前言

继续讲hook,本来是想按照能触发组件更新的顺序来,但是上一章讲了useTransition源码,而useDeferredValue和useTransition比较相似,所以先讲一讲。
官网的解释:useDeferredValue 是一个 React Hook,可以让你延迟更新 UI 的某些部分。
useDeferredValue也是通过降低优先级,可以被更高级的打断,达到延迟更新,在concurrent模式下能够更好的优化体验。

源码讲解

const deferredValue = useDeferredValue(value)

mount阶段

按照常规流程,调用HooksDispatcherOnMountInDEV.useReferredValue的方法,前置check检查方法,核心代码mountDeferredValue(value)
关于mountDeferredValue方法,先调用mountWorkInProgressHook方法,创建hook对象,更新hook.memoizedState = value,返回value值;

以下总结:

  • 创建hook对象,更新memoizedState的值;
  • mount阶段入参和返回值是一样的;

useDeferrendValue没有自己主动更新的,只有在更新过程中会将deferredValue不立即更新,而是延迟更新;

update阶段

调用HooksDispatcherOnUpdateInDEV.useDeferredValue方法,调用check方法,核心调用 updateDeferredValue(value) 方法,调用updateWorkInProgressHook方法,将current fiber上的浅copy一份,返回hook; 核心调用updateDeferredValueImpl(hook, prevValue, value) 方法,判断当前是不是shouldDeferValue,首次更新为true,只是更新当前fiber.lanes,和赋值hook.baseState = true,返回preValue,不会将最新的value返回。
将更新优先级低的任务执行中,shouldDeferValue为false,如果hook.baseState更新为false,同时hook.memoizedState = value赋值,返回最新的value。

以下总结:

  • 复制mount阶段创建的hook对象,
  • 判断是否是当前事件执行,如果不是将之前的value更新到hook.memoizedState,返回之前的值,如果当前执行,返回执行之后的值,并将value更新到hook.memoizedState;

与useTransition 对比

相同点

本质上都是为了做延迟处理,可以延迟更新处理,标记成优先级低任务,可以别高优先级的打断。

不同点

startTransition将callback内部的变成低优先级任务,而useDeferredValue处理原始值得到一个新的值,这个值作为延时状态。
useTransition是处理一段逻辑,而useDeferredValue生成一个新的值。
useTransition是有触发组件重新渲染的方法的,而useDeferredValue是没有能够主动触发更新的。