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

变异阶段前的反应

时间:2023-03-27 12:24:32 JavaScript

提交阶段分为三个部分。突变前阶段。突变阶段。布局阶段主要在commitRootImpl函数中调用。commitRootImpl只显示了调用beforemutation阶段的代码。以同步优先级执行,执行完成后恢复之前的优先级。constpreviousLanePriority=getCurrentUpdateLanePriority();setCurrentUpdateLanePriority(SyncLanePriority);//将当前上下文标记为CommitContext,作为提交阶段的标志constprevExecutionContext=executionContext;executionContext|=CommitContext;constprevInteractions=pushInteractions(root);//在调用生命周期之前将其重置为nullReactCurrentOwner.current=null;//提交阶段分为几个子阶段。我们为每个阶段单独传递//效果列表:所有变异效果都在所有之前//布局效果,依此类推。//第一阶段是“突变前”阶段。我们使用这个阶段来读取//主机树的状态,然后再改变它。这是调用getSnapshotBeforeUpdate的地方。focusedInstanceHandle=prepareForCommit(root.containe信息);shouldFireAfterActiveInstanceBlur=false;nextEffect=firstEffect;do{if(__DEV__){//....开发环境下调使用invokeGuardedCallback(null,commitBeforeMutationEffects,null);if(hasCaughtError()){invariant(nextEffect!==null,'应该处理一个效果。')??;consterror=clearCaughtError();captureCommitPhaseError(nextEffect,错误);nextEffect=nextEffect.nextEffect;}}else{try{//调用commitBeforeMutationEffectscommitBeforeMutationEffects();}catch(error){invariant(nextEffect!==null,'应该处理一个效果。')??;captureCommitPhaseError(nextEffect,错误);nextEffect=nextEffect.nextEffect;}}}while(nextEffect!==null);//....}invokeGuardedCallback启动环境下调使用commitBeforeMutationEffects函数invokeGuardedCallback(name,func,context,a,b,c,d,e,f){hasError=false;caughtError=null;调用瓜尔dedCallbackImpl$1.apply(reporter,arguments);}commitBeforeMutationEffects在突变前调用主要函数commitBeforeMutationEffects(){while(nextEffect!==null){constcurrent=nextEffect.alternate;if(!shouldFireAfterActiveInstanceBlur&&focusedInstanceHandle!==null){//...焦点模糊相关if((nextEffect.effectTag&Deletion)!==NoEffect){if(doesFiberContain(nextEffect,focusedInstanceHandle)){shouldFireAfterActiveInstanceBlur=true;beforeActiveInstanceBlur();}}else{//TODO:使用专用效果标签将其移出热路径。如果(nextEffect.tag===SuspenseComponent&&isSuspenseBoundaryBeingHidden(current,nextEffect)&&doesFiberContain(nextEffect,focusedInstanceHandle)){shouldFireAfterActiveInstanceBlur=true;beforeActiveInstanceBlur();}}}协nsteffectTag=nextEffect.effectTag;if((effectTag&Snapshot)!==NoEffect){setCurrentDebugFiberInDEV(nextEffect);//调用getSnapshotBeforeUpdatecommitBeforeMutationEffectOnFiber(current,nextEffect);resetCurrentDebugFiberInDEV();}//调度useEffectif((effectTag&Passive)!==NoEffect){//如果有被动效果,安排一个回调在//最早的机会刷新。如果(!rootDoesHavePassiveEffects){rootDoesHavePassiveEffects=true;scheduleCallback(NormalSchedulerPriority,()=>{flushPassiveEffects();returnnull;});}}nextEffect=nextEffect.nextEffect;}}commitBeforeMutationEffectOnFiber主要判别组件类,如果是类组件就执行getSnapshotBeforeUpdate生命周期functioncommitBeforeMutationLifeCycles(current:Fiber|null,finishedWork:Fiber,):void{switch(finishedWork.tag){caseFunctionComponent:caseForwardRef:caseSimpleMemoComponent:caseBlock:{返回;}caseClassComponent:{if(finishedWork.effectTag&Snapshot){if(current!==null){constprevProps=current.memoizedProps;constprevState=current.memoizedState;constinstance=finishedWork.stateNode;//我们可以在这里更新实例props和state,//但我们依赖于在上次渲染期间设置的它们。//TODO:当我们实现恢复时重新访问它。if(__DEV__){//....}//调用getSnapshotBeforeUpdate生命周期constsnapshot=instance.getSnapshotBeforeUpdate(finishedWork.elementType===finishedWork.type?prevProps:resolveDefaultProps(finishedWork.type,prevProps),prevState,);如果(__DEV__){//....}instance.__reactInternalSnapshotBeforeUpdate=sna拍摄;}}返回;}caseHostRoot:{if(supportsMutation){if(finishedWork.effectTag&Snapshot){constroot=finishedWork.stateNode;clearContainer(root.containerInfo);}}返回;}caseHostComponent:caseHostText:caseHostPortal:caseIncompleteClassComponent://对这些组件类型无事可做return;}invariant(false,'Thisunitofworktagshouldnothaveside-effects.Thiserroris'+'likelycausedbyabuginReact.Pleasefileanissue.',);}新版本生命周期。综上所述,本节主要学习突变前阶段的函数调用过程。commitRootImpl是commit阶段的主要功能。调用commitBeforeMutationEffectscommitBeforeMutationEffects的主要作用是:执行commitBeforeMutationEffectOnFiber,通过flushPassiveEffects调度useEffectcommitBeforeMutationEffectOnFiber。类组件getSnapshotBeforeUpdate的主要功能是通过判断组件类型来执行的。