We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
该 Hook 的返回值 startTransition 接收一个函数,函数内触发的更新都会被标记为低优先级,从而允许其它优先级更高的更新优先被处理。
对调试代码中的 useTranstion 打上断点,我们会在 mount 阶段时进入 mountTransition 这一函数。
function mountTransition(): [ boolean, (callback: () => void, options?: StartTransitionOptions) => void, ] { // useState 那篇文章内有介绍过,不再啰嗦 // 但这里可以看出 useTranstion 也会存在一个对应的 hook 实例(尽管是基于useState实现的) const [isPending, setPending] = mountState(false); // The `start` method never changes. // 此处是关键实现,下面会分析 const start = startTransition.bind(null, setPending); // hooks 链表里介绍过,不再啰嗦 const hook = mountWorkInProgressHook(); hook.memoizedState = start; return [isPending, start]; }
从代码中不难发现,关键的分析点在于 startTransition,因此我们看看它的实现是什么。
// 删掉了一些不重要的代码 function startTransition(setPending, callback, options) { // 创建变量缓存当前的 update 优先级 // 该优先级可被 getCurrentUpdatePriority 与 setCurrentUpdatePriority访问到 const previousPriority = getCurrentUpdatePriority(); setCurrentUpdatePriority( // 比较当前优先级与 ContinuousEventPriority 间谁更优先,并设置为当前的优先级 higherEventPriority(previousPriority, ContinuousEventPriority), ); // 这里通过调用 useState 的 dispatch 函数,创建了较高优先级的 update 实例 setPending(true); // 直接修改 ReactCurrentBatchConfig 的值,这将影响后续生成 update 的优先级 // 具体的代码可以看生成 update 实例时调用的 requestUpdateLane 函数 const prevTransition = ReactCurrentBatchConfig.transition; ReactCurrentBatchConfig.transition = {}; const currentTransition = ReactCurrentBatchConfig.transition; if (enableTransitionTracing) { if (options !== undefined && options.name !== undefined) { ReactCurrentBatchConfig.transition.name = options.name; ReactCurrentBatchConfig.transition.startTime = now(); } } // 总的来说,上面对 ReactCurrentBatchConfig 的操作将会影响下面的 setPending 与 callback 内生成的 update 实例的优先级,而其优先级必然是低于第一次调用 setPending 所生成的 update 实例的优先级的 // 而低优先级的 update 又会在处理状态更新时被跳过,这里在 useState 的文章里也有提及 try { setPending(false); callback(); } finally { // 这里是重置的操作,将优先级恢复到原先的状态 setCurrentUpdatePriority(previousPriority); ReactCurrentBatchConfig.transition = prevTransition; ... } }
很简单的一个钩子,总的原理便是将包裹在 callback 内所生成的更新打上低优先级的标记,从而让其他的更新优先处理。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
React Hooks: useTransition
说明
TLNR
该 Hook 的返回值 startTransition 接收一个函数,函数内触发的更新都会被标记为低优先级,从而允许其它优先级更高的更新优先被处理。
mount 阶段的 useTranstion
对调试代码中的 useTranstion 打上断点,我们会在 mount 阶段时进入 mountTransition 这一函数。
从代码中不难发现,关键的分析点在于 startTransition,因此我们看看它的实现是什么。
总结
很简单的一个钩子,总的原理便是将包裹在 callback 内所生成的更新打上低优先级的标记,从而让其他的更新优先处理。
The text was updated successfully, but these errors were encountered: