637
638
const NO_PENDING_EFFECTS = 0;
639
const PENDING_MUTATION_PHASE = 1;
640
-const PENDING_AFTER_MUTATION_PHASE = 2;
641
-const PENDING_LAYOUT_PHASE = 3;
642
-const PENDING_PASSIVE_PHASE = 4;
643
-let pendingEffectsStatus: 0 | 1 | 2 | 3 | 4 = 0;
640
+const PENDING_LAYOUT_PHASE = 2;
641
+const PENDING_AFTER_MUTATION_PHASE = 3;
642
+const PENDING_SPAWNED_WORK = 4;
643
+const PENDING_PASSIVE_PHASE = 5;
644
+let pendingEffectsStatus: 0 | 1 | 2 | 3 | 4 | 5 = 0;
645
let pendingEffectsRoot: FiberRoot = (null: any);
646
let pendingFinishedWork: Fiber = (null: any);
647
let pendingEffectsLanes: Lanes = NoLanes;
3433
startViewTransition(
3434
root.containerInfo,
3435
flushMutationEffects,
3435
- flushAfterMutationEffects,
3436
flushLayoutEffects,
3437
- // TODO: This flushes passive effects at the end of the transition but
3438
- // we also schedule work to flush them separately which we really shouldn't.
3439
- // We use flushPendingEffects instead of
3437
+ flushAfterMutationEffects,
3438
+ flushSpawnedWork,
3439
flushPassiveEffects,
3440
);
3441
if (!startedViewTransition) {
3442
// Flush synchronously.
3443
flushMutationEffects();
3445
- // Skip flushAfterMutationEffects
3446
- pendingEffectsStatus = PENDING_LAYOUT_PHASE;
3444
flushLayoutEffects();
3445
+ // Skip flushAfterMutationEffects
3446
+ flushSpawnedWork();
3447
}
3448
}
3449
3456
const finishedWork = pendingFinishedWork;
3457
const lanes = pendingEffectsLanes;
3458
commitAfterMutationEffects(root, finishedWork, lanes);
3460
- pendingEffectsStatus = PENDING_LAYOUT_PHASE;
3459
+ pendingEffectsStatus = PENDING_SPAWNED_WORK;
3460
}
3461
3462
function flushMutationEffects(): void {
3502
// componentWillUnmount, but before the layout phase, so that the finished
3503
// work is current during componentDidMount/Update.
3504
root.current = finishedWork;
3506
- pendingEffectsStatus = PENDING_AFTER_MUTATION_PHASE;
3505
+ pendingEffectsStatus = PENDING_LAYOUT_PHASE;
3506
}
3507
3508
function flushLayoutEffects(): void {
3510
- if (
3511
- pendingEffectsStatus !== PENDING_LAYOUT_PHASE &&
3512
- // If a startViewTransition times out, we might flush this earlier than
3513
- // after mutation phase. In that case, we just skip the after mutation phase.
3514
- pendingEffectsStatus !== PENDING_AFTER_MUTATION_PHASE
3515
- ) {
3509
+ if (pendingEffectsStatus !== PENDING_LAYOUT_PHASE) {
3510
return;
3511
}
3512
pendingEffectsStatus = NO_PENDING_EFFECTS;
3514
const root = pendingEffectsRoot;
3515
const finishedWork = pendingFinishedWork;
3516
const lanes = pendingEffectsLanes;
3523
- const completedRenderEndTime = pendingEffectsRenderEndTime;
3524
- const recoverableErrors = pendingRecoverableErrors;
3525
- const didIncludeRenderPhaseUpdate = pendingDidIncludeRenderPhaseUpdate;
3526
- const suspendedCommitReason = pendingSuspendedCommitReason;
3517
3518
const subtreeHasLayoutEffects =
3519
(finishedWork.subtreeFlags & LayoutMask) !== NoFlags;
3544
ReactSharedInternals.T = prevTransition;
3545
}
3546
}
3547
+ pendingEffectsStatus = PENDING_AFTER_MUTATION_PHASE;
3548
+}
3549
+
3550
+function flushSpawnedWork(): void {
3551
+ if (
3552
+ pendingEffectsStatus !== PENDING_SPAWNED_WORK &&
3553
+ // If a startViewTransition times out, we might flush this earlier than
3554
+ // after mutation phase. In that case, we just skip the after mutation phase.
3555
+ pendingEffectsStatus !== PENDING_AFTER_MUTATION_PHASE
3556
+ ) {
3557
+ return;
3558
+ }
3559
+ pendingEffectsStatus = NO_PENDING_EFFECTS;
3560
3561
// Tell Scheduler to yield at the end of the frame, so the browser has an
3562
// opportunity to paint.
3563
requestPaint();
3564
3565
+ const root = pendingEffectsRoot;
3566
+ const finishedWork = pendingFinishedWork;
3567
+ const lanes = pendingEffectsLanes;
3568
+ const completedRenderEndTime = pendingEffectsRenderEndTime;
3569
+ const recoverableErrors = pendingRecoverableErrors;
3570
+ const didIncludeRenderPhaseUpdate = pendingDidIncludeRenderPhaseUpdate;
3571
+ const suspendedCommitReason = pendingSuspendedCommitReason;
3572
+
3573
if (enableProfilerTimer && enableComponentPerformanceTrack) {
3574
recordCommitEndTime();
3575
logCommitPhase(
3806
// Returns whether passive effects were flushed.
3807
flushMutationEffects();
3808
flushLayoutEffects();
3809
+ // Skip flushAfterMutation if we're forcing this early.
3810
+ flushSpawnedWork();
3811
return flushPassiveEffects(wasDelayedCommit);
3812
}
3813