# 阅读图解React笔记7
3 min read
Table of Contents
本文仅仅是阅读 图解 React 原理系列 的笔记,了解更多内容请查看原文链接。
概览
Fiber 树渲染阶段被称为 commit 阶段。fiberNode 阶段流程可能被打断,而 commit 阶段一旦开始就会同步执行直到完成。
整个阶段可以分为三个子阶段:
- BeforeMutation 阶段
- Mutation 阶段
- Layout 阶段
CommitRoot
整个渲染逻辑都在 CommitRootImpl 函数上,其源码位置 ReactFiberWorkLoop.new.js
在 commitRoot 中同时使用到了渲染优先级和调度优先级,最后的实现是通过 commitRootImpl 函数:
function commitRootImpl(root, recoverableErrors, transitions, renderPriorityLevel) { // ============ // 渲染前准备 // ============ const finishedWork = root.finishedWork const lanes = root.finishedLanes
// 清空 FiberRoot 对象上的属性 root.finishedWork = null root.finishedLanes = NoLanes root.callbackNode = null
if (root === workInProgressRoot) { workInProgressRoot = null workInProgress = null workInProgressRootRenderLanes = NoLanes }
// ======== // 渲染 // ======== // 检查是否有副作用在整个树 const subtreeHasEffect = (finishedWork.subtreeFlags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags const rootHasEffect = (finishedWork.flags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags
if (subtreeHasEffect || rootHasEffect) { const prevExecutionContext = executionContext executionContext |= CommitContext const prevInteractions = pushInteractions(root)
// 调用生命周期前,重置为null ReactCurrentOwner.current = null
// 第一个阶段 commitBeforeMutationEffects(finishedWork)
// 第二个阶段 commitMutationEffects(finishedWork, root, renderPriorityLevel)
// fiber 树的切换 root.current = finishedWork
// 第三个阶段 commitLayoutEffects(finishedWork, root, lanes)
// 如果有被动的副作用,调度一个回调处理它。 if ( (finishedWork.subtreeFlags & PassiveMask) !== NoFlags || (finishedWork.flags & PassiveMask) !== NoFlags ) { if (!rootDoesHavePassiveEffects) { rootDoesHavePassiveEffects = true scheduleCallback(NormalSchedulerPriority, () => { flushPassiveEffecs() return null }) } }
// 告知调度器在帧的末尾产生,所以浏览器能有机会绘制。 requestPaint()
// ========= // 渲染后 // ========= const rootDidHavePassiveEffects = rootDoesHavePassiveEffects
if (rootDoesHavePassiveEffects) { // 这次 commit 有被动副作用,保存对它们的引用。 rootDoesHavePassiveEffects = false rootWithPendingPassiveEffects = root pendingPassiveEffectsLanes = lanes } else { releaseRootPooledCache(root, remainingLanes) }
// 结束之前总是要调用该函数,确保当前 root 所有额外的工作的被调度。 ensureRootIsScheduled(root, now())
// 如果布局被调度了,刷新它 flushSyncCallbackQueue()
return null }}大致可以将 commitRootImpl 划分为渲染前,渲染,渲染后。
渲染前主要是设置一些全局变量和重置一些全局状态。
渲染被划分为 3 个阶段处理实现:
- commitBeforeMutationEffects
- commitMutationEffects
- recursivelyCommitLayoutEffects
渲染后主要做一些重置和清理工作。