此阶段处理的工作
- 处理与focus和blur事件

- 如果effect Tag包含Snapshot,即ClassComponent对应的getSnapshotBeforeUpdate,处理commitBeforeMutationEffectsOnFiber。

- 如果有effectTag,effectTag包含passive时,即FunctionComponent中对对应的useEffect的effect tag,需要调度flushPassiveEffects()
commitBeforeMutationEffectsOnFiber
如果effect Tag包含Snapshot,进入commitBeforeMutationEffectsOnFiber。如果是ClassComponent,就会 var instance = finishedWork.stateNode,获得component的实例,调用实例上的getSnapshotBeforeUpdate生命周期。
因此getSnapshotBeforeUpdate,是在before mutation上调用,此时还没有页面可见的更新。
function commitBeforeMutationEffectsOnFiber(finishedWork) {var current = finishedWork.alternate;var flags = finishedWork.flags;if ((flags & Snapshot) !== NoFlags) {setCurrentFiber(finishedWork);switch (finishedWork.tag) {case FunctionComponent:case ForwardRef:case SimpleMemoComponent:{break;}//如果是ClassComponentcase ClassComponent:{if (current !== null) {var prevProps = current.memoizedProps;var prevState = current.memoizedState;var instance = finishedWork.stateNode;....var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);{var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {didWarnSet.add(finishedWork.type);error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentNameFromFiber(finishedWork));}}instance.__reactInternalSnapshotBeforeUpdate = snapshot;}break;}case HostRoot:{{var root = finishedWork.stateNode;clearContainer(root.containerInfo);}break;}case HostComponent:case HostText:case HostPortal:case IncompleteClassComponent:// Nothing to do for these component typesbreak;default:{throw new Error('This unit of work tag should not have side-effects. This error is ' + 'likely caused by a bug in React. Please file an issue.');}}resetCurrentFiber();}}
flushPassiveEffects
如果effectTag包含passive,此时并没有直接执行flushPassiveEffects。flushPassiveEffects会执行useEffect的回调函数。
为什么逻辑中没有直接执行flushPassiveEffects,而是作为scheduleCallback的回调函数?
scheduleCallback()会以一个优先级,来异步执行一个回调函数。如果一个FunctionComponent存在一个useEffect,并且他的useEffect的回调函数需要被触发的情况下,那么这个useEffect的回调会在before mutation阶段,先被NormalSchedulePriority的优先级调度。
而整个commit阶段是同步执行的,所以useEffect回调函数的执行,是在commit阶段完成以后,再异步执行的。
