Unify RootDidNotComplete and RootSuspendedWithDelay exit path (#31547)
Also rename RootDidNotComplete to RootSuspendedAtTheShell since it specifically means something suspended in the shell during hydration.
Sebastian Markbåge committed
Nov 14, 2024 at 23:51 UTC
8a41d6ceab8af642d8ab9ed04fc744a699f4ac09
1 file changed
+25
-32
packages/react-reconciler/src/ReactFiberWorkLoop.js
+25
-32
@@ -329,8 +329,8 @@ const RootFatalErrored = 1;
329
const RootErrored = 2;
330
const RootSuspended = 3;
331
const RootSuspendedWithDelay = 4;
332
+const RootSuspendedAtTheShell = 6;
333
const RootCompleted = 5;
333
-const RootDidNotComplete = 6;
334
335
// Describes where we are in the React execution stack
336
let executionContext: ExecutionContext = NoContext;
@@ -942,15 +942,6 @@ export function performWorkOnRoot(
942
markRootSuspended(root, lanes, NoLane, didAttemptEntireTree);
943
}
944
break;
945
- } else if (exitStatus === RootDidNotComplete) {
946
- if (enableProfilerTimer && enableComponentPerformanceTrack) {
947
- finalizeRender(lanes, now());
948
- }
949
- // The render unwound without completing the tree. This happens in special
950
- // cases where need to exit the current render without producing a
951
- // consistent tree or committing.
952
- const didAttemptEntireTree = !workInProgressRootDidSkipSuspendedSiblings;
953
- markRootSuspended(root, lanes, NoLane, didAttemptEntireTree);
945
} else {
946
// The render completed.
947
@@ -998,7 +989,7 @@ export function performWorkOnRoot(
989
// from the beginning.
990
// TODO: Refactor the exit algorithm to be less confusing. Maybe
991
// more branches + recursion instead of a loop. I think the only
1001
- // thing that causes it to be a loop is the RootDidNotComplete
992
+ // thing that causes it to be a loop is the RootSuspendedAtTheShell
993
// check. If that's true, then we don't need a loop/recursion
994
// at all.
995
continue;
@@ -1134,25 +1125,27 @@ function finishConcurrentRender(
1125
throw new Error('Root did not complete. This is a bug in React.');
1126
}
1127
case RootSuspendedWithDelay: {
1137
- if (includesOnlyTransitions(lanes)) {
1138
- // This is a transition, so we should exit without committing a
1139
- // placeholder and without scheduling a timeout. Delay indefinitely
1140
- // until we receive more data.
1141
- if (enableProfilerTimer && enableComponentPerformanceTrack) {
1142
- finalizeRender(lanes, now());
1143
- }
1144
- const didAttemptEntireTree =
1145
- !workInProgressRootDidSkipSuspendedSiblings;
1146
- markRootSuspended(
1147
- root,
1148
- lanes,
1149
- workInProgressDeferredLane,
1150
- didAttemptEntireTree,
1151
- );
1152
- return;
1128
+ if (!includesOnlyTransitions(lanes)) {
1129
+ // Commit the placeholder.
1130
+ break;
1131
}
1154
- // Commit the placeholder.
1155
- break;
1132
+ }
1133
+ // Fallthrough
1134
+ case RootSuspendedAtTheShell: {
1135
+ // This is a transition, so we should exit without committing a
1136
+ // placeholder and without scheduling a timeout. Delay indefinitely
1137
+ // until we receive more data.
1138
+ if (enableProfilerTimer && enableComponentPerformanceTrack) {
1139
+ finalizeRender(lanes, renderEndTime);
1140
+ }
1141
+ const didAttemptEntireTree = !workInProgressRootDidSkipSuspendedSiblings;
1142
+ markRootSuspended(
1143
+ root,
1144
+ lanes,
1145
+ workInProgressDeferredLane,
1146
+ didAttemptEntireTree,
1147
+ );
1148
+ return;
1149
}
1150
case RootErrored: {
1151
// This render errored. Ignore any recoverable errors because we weren't actually
@@ -2146,7 +2139,7 @@ function renderRootSync(
2139
// just yield and reset the stack when we re-enter the work loop,
2140
// like normal.
2141
resetWorkInProgressStack();
2149
- exitStatus = RootDidNotComplete;
2142
+ exitStatus = RootSuspendedAtTheShell;
2143
break outer;
2144
}
2145
case SuspendedOnImmediate:
@@ -2465,7 +2458,7 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
2458
// Interrupt the current render so the work loop can switch to the
2459
// hydration lane.
2460
resetWorkInProgressStack();
2468
- workInProgressRootExitStatus = RootDidNotComplete;
2461
+ workInProgressRootExitStatus = RootSuspendedAtTheShell;
2462
break outer;
2463
}
2464
default: {
@@ -2973,7 +2966,7 @@ function unwindUnitOfWork(unitOfWork: Fiber, skipSiblings: boolean): void {
2966
} while (incompleteWork !== null);
2967
2968
// We've unwound all the way to the root.
2976
- workInProgressRootExitStatus = RootDidNotComplete;
2969
+ workInProgressRootExitStatus = RootSuspendedAtTheShell;
2970
workInProgress = null;
2971
}
2972