前言
继续讲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是没有能够主动触发更新的。