当前位置: 首页 > Web前端 > HTML

Reactcommit阶段分析——前期学习

时间:2023-03-28 16:28:57 HTML

renderRootSync执行完render相关的阶段后,就会进入commit阶段。在performSyncWorkOnRoot函数结束时,调用commitRoot(root);commit阶段的工作保存了一个单向链表effectList需要对rootFiber.firstEffect进行副作用的Fiber节点,这些Fiber节点的updateQueue保存了变化的props。这些副作用对应的DOM操作是在提交阶段执行的。另外,一些生命周期钩子(如componentDidXXX)和钩子(如useEffect)需要在commit阶段执行。commit阶段的主要工作分为三个部分:beforemutationstage(执行DOM操作之前)mutation阶段(执行DOM操作)layout阶段(执行DOM操作之后)commitRootcommit阶段的起点是将fiberNode传入functioncommitRoot(root){//getCurrentPriorityLevel调度优先级相关constrenderPriorityLevel=getCurrentPriorityLevel();runWithPriority(ImmediateSchedulerPriority,commitRootImpl.bind(null,root,renderPriorityLevel),);returnnull;}commitRootImpl有300多行代码,主要包括pre-commitwork文章第三阶段的执行,下面的代码主要是pre-commit阶段前置工作:调用flushPassiveEffects执行所有effect任务,初始化相关变量,赋值firstEffect用于后续遍历effectList,usefunctioncommitRootImpl(root,renderPriorityLevel){do{//触发useEffect回调等同步任务。由于这些任务可能会触发新的渲染,所以需要遍历执行到没有任务为止flushPassiveEffects();}while(rootWithPendingPassiveEffects!==null);//指向当前应用的rootFiberconst//priorityconstlanes=root.finishedLanes;if(finishedWork===null){returnnull;}//重置变量root.finishedWork=null;root.finishedLanes=NoLanes;//调度回调函数重置root.callbackNode=null;root.callbackId=NoLanes;//合并并清除优先级letremainingLanes=mergeLanes(finishedWork.lanes,finishedWork.childLanes);markRootFinished(root,remainingLanes);//清除完成的离散更新,例如:用户鼠标点击触发的更新.如果(rootsWithPendingDiscreteUpdates!==null){如果(!hasDiscreteLanes(remainingLanes)&&rootsWithPendingDiscreteUpdates.has(root)){rootsWithPendingDiscreteUpdates.delete(root);}}//重置全局变量if(root===workInProgressRoot){workInProgressRoot=null;workInProgress=null;workInProgressRootRenderLanes=NoLanes;}else{}//将effectList的副作用分配给firstEffectletfirstEffect;if(finishedWork.effectTag>PerformedWork){if(finishedWork.lastEffect!==null){firstEffect=finishedWork.firstEffect;}else{firstEffect=finishedWork;}}else{firstEffect=finishedWork.firstEffect;}}flushPassiveEffects先设置优先级,然后调用flushPassiveEffectsImpl执行所有效果任务正常调度ulerPriority:pendingPassiveEffectsRenderPriority;pendingPassiveEffectsRenderPriority=NoSchedulerPriority;constpreviousLanePriority=getCurrentUpdateLanePriority();尝试{setCurrentUpdateLanePriority(schedulerPriorityToLanePriority(priorityLevel),);返回runWithPriority(priorityLevel,flushPassiveEffectsImpl);}最后{setCurrentUpdateLanePriority(previousLanePriority);}}}总结这篇主要是看了commitRootImpl函数的代码,了解到函数执行过程分为三个不同的过程:beforemutationstage(执行DOM操作之前),mutationstage(执行DOM操作),以及布局阶段(在执行DOM操作之后)。