( root: FiberRoot, finishedWork: null | Fiber, lanes: Lanes, recoverableErrors: null | Array<CapturedValue<mixed>>, transitions: Array<Transition> | null, didIncludeRenderPhaseUpdate: boolean, spawnedLane: Lane, updatedLanes: Lanes, suspendedRetryLanes: Lanes, exitStatus: RootExitStatus, suspendedState: null | SuspendedState, suspendedCommitReason: SuspendedCommitReason, // Profiling-only completedRenderStartTime: number, // Profiling-only completedRenderEndTime: number, // Profiling-only )
| 3414 | } |
| 3415 | |
| 3416 | function commitRoot( |
| 3417 | root: FiberRoot, |
| 3418 | finishedWork: null | Fiber, |
| 3419 | lanes: Lanes, |
| 3420 | recoverableErrors: null | Array<CapturedValue<mixed>>, |
| 3421 | transitions: Array<Transition> | null, |
| 3422 | didIncludeRenderPhaseUpdate: boolean, |
| 3423 | spawnedLane: Lane, |
| 3424 | updatedLanes: Lanes, |
| 3425 | suspendedRetryLanes: Lanes, |
| 3426 | exitStatus: RootExitStatus, |
| 3427 | suspendedState: null | SuspendedState, |
| 3428 | suspendedCommitReason: SuspendedCommitReason, // Profiling-only |
| 3429 | completedRenderStartTime: number, // Profiling-only |
| 3430 | completedRenderEndTime: number, // Profiling-only |
| 3431 | ): void { |
| 3432 | root.cancelPendingCommit = null; |
| 3433 | |
| 3434 | do { |
| 3435 | // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which |
| 3436 | // means `flushPassiveEffects` will sometimes result in additional |
| 3437 | // passive effects. So we need to keep flushing in a loop until there are |
| 3438 | // no more pending effects. |
| 3439 | // TODO: Might be better if `flushPassiveEffects` did not automatically |
| 3440 | // flush synchronous work at the end, to avoid factoring hazards like this. |
| 3441 | flushPendingEffects(); |
| 3442 | } while (pendingEffectsStatus !== NO_PENDING_EFFECTS); |
| 3443 | flushRenderPhaseStrictModeWarningsInDEV(); |
| 3444 | |
| 3445 | if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { |
| 3446 | throw new Error('Should not already be working.'); |
| 3447 | } |
| 3448 | |
| 3449 | if (enableProfilerTimer && enableComponentPerformanceTrack) { |
| 3450 | // Log the previous render phase once we commit. I.e. we weren't interrupted. |
| 3451 | setCurrentTrackFromLanes(lanes); |
| 3452 | if (exitStatus === RootErrored) { |
| 3453 | logErroredRenderPhase( |
| 3454 | completedRenderStartTime, |
| 3455 | completedRenderEndTime, |
| 3456 | lanes, |
| 3457 | workInProgressUpdateTask, |
| 3458 | ); |
| 3459 | } else if (recoverableErrors !== null) { |
| 3460 | const hydrationFailed = |
| 3461 | finishedWork !== null && |
| 3462 | finishedWork.alternate !== null && |
| 3463 | (finishedWork.alternate.memoizedState: RootState).isDehydrated && |
| 3464 | (finishedWork.flags & ForceClientRender) !== NoFlags; |
| 3465 | logRecoveredRenderPhase( |
| 3466 | completedRenderStartTime, |
| 3467 | completedRenderEndTime, |
| 3468 | lanes, |
| 3469 | recoverableErrors, |
| 3470 | hydrationFailed, |
| 3471 | workInProgressUpdateTask, |
| 3472 | ); |
| 3473 | } else { |
no test coverage detected