Pass ThenableState to replaySuspendedUnitOfWork
Tiny refactor to refine the work loop variable so Flow knows it's not null when we access it in replaySuspendedUnitOfWork.
Andrew Clark committed
Nov 2, 2022 at 14:18 UTC
5eb78d0a04dee8fa14189a31c19831dd390225cb
2 files changed
+80
-52
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
+40
-26
@@ -2202,24 +2202,29 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
2202
break;
2203
}
2204
case SuspendedOnData: {
2205
- const didResolve =
2206
- workInProgressSuspendedThenableState !== null &&
2207
- isThenableStateResolved(workInProgressSuspendedThenableState);
2208
- if (didResolve) {
2209
- workInProgressSuspendedReason = NotSuspended;
2210
- workInProgressThrownValue = null;
2211
- replaySuspendedUnitOfWork(unitOfWork, thrownValue);
2212
- } else {
2213
- // The work loop is suspended on data. We should wait for it to
2214
- // resolve before continuing to render.
2215
- const thenable: Thenable<mixed> = (workInProgressThrownValue: any);
2216
- const onResolution = () => {
2217
- ensureRootIsScheduled(root, now());
2218
- };
2219
- thenable.then(onResolution, onResolution);
2220
- break outer;
2205
+ if (workInProgressSuspendedThenableState !== null) {
2206
+ const thenableState = workInProgressSuspendedThenableState;
2207
+ if (isThenableStateResolved(thenableState)) {
2208
+ // The data resolved. Try rendering the component again.
2209
+ workInProgressSuspendedReason = NotSuspended;
2210
+ workInProgressThrownValue = null;
2211
+ replaySuspendedUnitOfWork(
2212
+ unitOfWork,
2213
+ thrownValue,
2214
+ thenableState,
2215
+ );
2216
+ break;
2217
+ }
2218
}
2222
- break;
2219
+
2220
+ // The work loop is suspended on data. We should wait for it to
2221
+ // resolve before continuing to render.
2222
+ const thenable: Thenable<mixed> = (workInProgressThrownValue: any);
2223
+ const onResolution = () => {
2224
+ ensureRootIsScheduled(root, now());
2225
+ };
2226
+ thenable.then(onResolution, onResolution);
2227
+ break outer;
2228
}
2229
case SuspendedOnImmediate: {
2230
// If this fiber just suspended, it's possible the data is already
@@ -2237,17 +2242,25 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
2242
break outer;
2243
}
2244
default: {
2245
+ if (workInProgressSuspendedThenableState !== null) {
2246
+ const thenableState = workInProgressSuspendedThenableState;
2247
+ if (isThenableStateResolved(thenableState)) {
2248
+ // The data resolved. Try rendering the component again.
2249
+ workInProgressSuspendedReason = NotSuspended;
2250
+ workInProgressThrownValue = null;
2251
+ replaySuspendedUnitOfWork(
2252
+ unitOfWork,
2253
+ thrownValue,
2254
+ thenableState,
2255
+ );
2256
+ break;
2257
+ }
2258
+ }
2259
+
2260
+ // Otherwise, unwind then continue with the normal work loop.
2261
workInProgressSuspendedReason = NotSuspended;
2262
workInProgressThrownValue = null;
2242
- const didResolve =
2243
- workInProgressSuspendedThenableState !== null &&
2244
- isThenableStateResolved(workInProgressSuspendedThenableState);
2245
- if (didResolve) {
2246
- replaySuspendedUnitOfWork(unitOfWork, thrownValue);
2247
- } else {
2248
- unwindSuspendedUnitOfWork(unitOfWork, thrownValue);
2249
- }
2250
- // Continue with the normal work loop.
2263
+ unwindSuspendedUnitOfWork(unitOfWork, thrownValue);
2264
break;
2265
}
2266
}
@@ -2335,6 +2348,7 @@ function performUnitOfWork(unitOfWork: Fiber): void {
2348
function replaySuspendedUnitOfWork(
2349
unitOfWork: Fiber,
2350
thrownValue: mixed,
2351
+ thenableState: ThenableState,
2352
): void {
2353
// This is a fork of performUnitOfWork specifcally for replaying a fiber that
2354
// just suspended.
packages/react-reconciler/src/ReactFiberWorkLoop.old.js
+40
-26
@@ -2202,24 +2202,29 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
2202
break;
2203
}
2204
case SuspendedOnData: {
2205
- const didResolve =
2206
- workInProgressSuspendedThenableState !== null &&
2207
- isThenableStateResolved(workInProgressSuspendedThenableState);
2208
- if (didResolve) {
2209
- workInProgressSuspendedReason = NotSuspended;
2210
- workInProgressThrownValue = null;
2211
- replaySuspendedUnitOfWork(unitOfWork, thrownValue);
2212
- } else {
2213
- // The work loop is suspended on data. We should wait for it to
2214
- // resolve before continuing to render.
2215
- const thenable: Thenable<mixed> = (workInProgressThrownValue: any);
2216
- const onResolution = () => {
2217
- ensureRootIsScheduled(root, now());
2218
- };
2219
- thenable.then(onResolution, onResolution);
2220
- break outer;
2205
+ if (workInProgressSuspendedThenableState !== null) {
2206
+ const thenableState = workInProgressSuspendedThenableState;
2207
+ if (isThenableStateResolved(thenableState)) {
2208
+ // The data resolved. Try rendering the component again.
2209
+ workInProgressSuspendedReason = NotSuspended;
2210
+ workInProgressThrownValue = null;
2211
+ replaySuspendedUnitOfWork(
2212
+ unitOfWork,
2213
+ thrownValue,
2214
+ thenableState,
2215
+ );
2216
+ break;
2217
+ }
2218
}
2222
- break;
2219
+
2220
+ // The work loop is suspended on data. We should wait for it to
2221
+ // resolve before continuing to render.
2222
+ const thenable: Thenable<mixed> = (workInProgressThrownValue: any);
2223
+ const onResolution = () => {
2224
+ ensureRootIsScheduled(root, now());
2225
+ };
2226
+ thenable.then(onResolution, onResolution);
2227
+ break outer;
2228
}
2229
case SuspendedOnImmediate: {
2230
// If this fiber just suspended, it's possible the data is already
@@ -2237,17 +2242,25 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
2242
break outer;
2243
}
2244
default: {
2245
+ if (workInProgressSuspendedThenableState !== null) {
2246
+ const thenableState = workInProgressSuspendedThenableState;
2247
+ if (isThenableStateResolved(thenableState)) {
2248
+ // The data resolved. Try rendering the component again.
2249
+ workInProgressSuspendedReason = NotSuspended;
2250
+ workInProgressThrownValue = null;
2251
+ replaySuspendedUnitOfWork(
2252
+ unitOfWork,
2253
+ thrownValue,
2254
+ thenableState,
2255
+ );
2256
+ break;
2257
+ }
2258
+ }
2259
+
2260
+ // Otherwise, unwind then continue with the normal work loop.
2261
workInProgressSuspendedReason = NotSuspended;
2262
workInProgressThrownValue = null;
2242
- const didResolve =
2243
- workInProgressSuspendedThenableState !== null &&
2244
- isThenableStateResolved(workInProgressSuspendedThenableState);
2245
- if (didResolve) {
2246
- replaySuspendedUnitOfWork(unitOfWork, thrownValue);
2247
- } else {
2248
- unwindSuspendedUnitOfWork(unitOfWork, thrownValue);
2249
- }
2250
- // Continue with the normal work loop.
2263
+ unwindSuspendedUnitOfWork(unitOfWork, thrownValue);
2264
break;
2265
}
2266
}
@@ -2335,6 +2348,7 @@ function performUnitOfWork(unitOfWork: Fiber): void {
2348
function replaySuspendedUnitOfWork(
2349
unitOfWork: Fiber,
2350
thrownValue: mixed,
2351
+ thenableState: ThenableState,
2352
): void {
2353
// This is a fork of performUnitOfWork specifcally for replaying a fiber that
2354
// just suspended.