Skip to content

Commit 27a255c

Browse files
committed
Extract retry effect code to shared function
There are several fiber types that can act like a Suspense boundary: Suspense, SuspenseList, and Offscreen. This extracts the code for scheduling a retry on those fibers into a shared function. In a later step I'm going to modify how retries work. Refactor only, no behavior change.
1 parent 08d9451 commit 27a255c

File tree

6 files changed

+63
-53
lines changed

6 files changed

+63
-53
lines changed

packages/react-reconciler/src/ReactFiberBeginWork.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2298,7 +2298,7 @@ function updateSuspenseComponent(
22982298
const newOffscreenQueue: OffscreenQueue = {
22992299
transitions: currentTransitions,
23002300
markerInstances: parentMarkerInstances,
2301-
wakeables: null,
2301+
retryQueue: null,
23022302
};
23032303
primaryChildFragment.updateQueue = newOffscreenQueue;
23042304
} else {
@@ -2399,7 +2399,7 @@ function updateSuspenseComponent(
23992399
const newOffscreenQueue: OffscreenQueue = {
24002400
transitions: currentTransitions,
24012401
markerInstances: parentMarkerInstances,
2402-
wakeables: null,
2402+
retryQueue: null,
24032403
};
24042404
primaryChildFragment.updateQueue = newOffscreenQueue;
24052405
} else if (offscreenQueue === currentOffscreenQueue) {
@@ -2408,9 +2408,9 @@ function updateSuspenseComponent(
24082408
const newOffscreenQueue: OffscreenQueue = {
24092409
transitions: currentTransitions,
24102410
markerInstances: parentMarkerInstances,
2411-
wakeables:
2411+
retryQueue:
24122412
currentOffscreenQueue !== null
2413-
? currentOffscreenQueue.wakeables
2413+
? currentOffscreenQueue.retryQueue
24142414
: null,
24152415
};
24162416
primaryChildFragment.updateQueue = newOffscreenQueue;

packages/react-reconciler/src/ReactFiberCommitWork.js

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import type {
1919
import type {Fiber, FiberRoot} from './ReactInternalTypes';
2020
import type {Lanes} from './ReactFiberLane';
2121
import {NoTimestamp, SyncLane} from './ReactFiberLane';
22-
import type {SuspenseState} from './ReactFiberSuspenseComponent';
22+
import type {SuspenseState, RetryQueue} from './ReactFiberSuspenseComponent';
2323
import type {UpdateQueue} from './ReactFiberClassUpdateQueue';
2424
import type {FunctionComponentUpdateQueue} from './ReactFiberHooks';
2525
import type {Wakeable} from 'shared/ReactTypes';
@@ -2310,9 +2310,9 @@ function commitSuspenseCallback(finishedWork: Fiber) {
23102310
if (enableSuspenseCallback && newState !== null) {
23112311
const suspenseCallback = finishedWork.memoizedProps.suspenseCallback;
23122312
if (typeof suspenseCallback === 'function') {
2313-
const wakeables: Set<Wakeable> | null = (finishedWork.updateQueue: any);
2314-
if (wakeables !== null) {
2315-
suspenseCallback(new Set(wakeables));
2313+
const retryQueue: RetryQueue | null = (finishedWork.updateQueue: any);
2314+
if (retryQueue !== null) {
2315+
suspenseCallback(new Set(retryQueue));
23162316
}
23172317
} else if (__DEV__) {
23182318
if (suspenseCallback !== undefined) {
@@ -2431,7 +2431,7 @@ export function attachOffscreenInstance(instance: OffscreenInstance): void {
24312431

24322432
function attachSuspenseRetryListeners(
24332433
finishedWork: Fiber,
2434-
wakeables: Set<Wakeable>,
2434+
wakeables: RetryQueue,
24352435
) {
24362436
// If this boundary just timed out, then it will have a set of wakeables.
24372437
// For each wakeable, attach a listener so that when it resolves, React
@@ -2917,10 +2917,10 @@ function commitMutationEffectsOnFiber(
29172917
} catch (error) {
29182918
captureCommitPhaseError(finishedWork, finishedWork.return, error);
29192919
}
2920-
const wakeables: Set<Wakeable> | null = (finishedWork.updateQueue: any);
2921-
if (wakeables !== null) {
2920+
const retryQueue: RetryQueue | null = (finishedWork.updateQueue: any);
2921+
if (retryQueue !== null) {
29222922
finishedWork.updateQueue = null;
2923-
attachSuspenseRetryListeners(finishedWork, wakeables);
2923+
attachSuspenseRetryListeners(finishedWork, retryQueue);
29242924
}
29252925
}
29262926
return;
@@ -3006,10 +3006,10 @@ function commitMutationEffectsOnFiber(
30063006
const offscreenQueue: OffscreenQueue | null =
30073007
(finishedWork.updateQueue: any);
30083008
if (offscreenQueue !== null) {
3009-
const wakeables = offscreenQueue.wakeables;
3010-
if (wakeables !== null) {
3011-
offscreenQueue.wakeables = null;
3012-
attachSuspenseRetryListeners(finishedWork, wakeables);
3009+
const retryQueue = offscreenQueue.retryQueue;
3010+
if (retryQueue !== null) {
3011+
offscreenQueue.retryQueue = null;
3012+
attachSuspenseRetryListeners(finishedWork, retryQueue);
30133013
}
30143014
}
30153015
}
@@ -3020,10 +3020,11 @@ function commitMutationEffectsOnFiber(
30203020
commitReconciliationEffects(finishedWork);
30213021

30223022
if (flags & Update) {
3023-
const wakeables: Set<Wakeable> | null = (finishedWork.updateQueue: any);
3024-
if (wakeables !== null) {
3023+
const retryQueue: Set<Wakeable> | null =
3024+
(finishedWork.updateQueue: any);
3025+
if (retryQueue !== null) {
30253026
finishedWork.updateQueue = null;
3026-
attachSuspenseRetryListeners(finishedWork, wakeables);
3027+
attachSuspenseRetryListeners(finishedWork, retryQueue);
30273028
}
30283029
}
30293030
return;

packages/react-reconciler/src/ReactFiberCompleteWork.js

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,7 @@
1010
import type {Fiber, FiberRoot} from './ReactInternalTypes';
1111
import type {RootState} from './ReactFiberRoot';
1212
import type {Lanes, Lane} from './ReactFiberLane';
13-
import type {
14-
ReactScopeInstance,
15-
ReactContext,
16-
Wakeable,
17-
} from 'shared/ReactTypes';
13+
import type {ReactScopeInstance, ReactContext} from 'shared/ReactTypes';
1814
import type {
1915
Instance,
2016
Type,
@@ -25,7 +21,9 @@ import type {
2521
import type {
2622
SuspenseState,
2723
SuspenseListRenderState,
24+
RetryQueue,
2825
} from './ReactFiberSuspenseComponent';
26+
import type {OffscreenQueue} from './ReactFiberOffscreenComponent';
2927
import {isOffscreenManual} from './ReactFiberOffscreenComponent';
3028
import type {OffscreenState} from './ReactFiberOffscreenComponent';
3129
import type {TracingMarkerInstance} from './ReactFiberTracingMarkerComponent';
@@ -502,6 +500,19 @@ function updateHostComponent(
502500
}
503501
}
504502
}
503+
504+
function scheduleRetryEffect(
505+
workInProgress: Fiber,
506+
retryQueue: RetryQueue | null,
507+
) {
508+
const wakeables = retryQueue;
509+
if (wakeables !== null) {
510+
// Schedule an effect to attach a retry listener to the promise.
511+
// TODO: Move to passive phase
512+
workInProgress.flags |= Update;
513+
}
514+
}
515+
505516
function updateHostText(
506517
current: Fiber,
507518
workInProgress: Fiber,
@@ -1227,12 +1238,8 @@ function completeWork(
12271238
}
12281239
}
12291240

1230-
const wakeables: Set<Wakeable> | null = (workInProgress.updateQueue: any);
1231-
if (wakeables !== null) {
1232-
// Schedule an effect to attach a retry listener to the promise.
1233-
// TODO: Move to passive phase
1234-
workInProgress.flags |= Update;
1235-
}
1241+
const retryQueue: RetryQueue | null = (workInProgress.updateQueue: any);
1242+
scheduleRetryEffect(workInProgress, retryQueue);
12361243

12371244
if (
12381245
enableSuspenseCallback &&
@@ -1337,11 +1344,10 @@ function completeWork(
13371344
// We might bail out of the loop before finding any but that
13381345
// doesn't matter since that means that the other boundaries that
13391346
// we did find already has their listeners attached.
1340-
const newThenables = suspended.updateQueue;
1341-
if (newThenables !== null) {
1342-
workInProgress.updateQueue = newThenables;
1343-
workInProgress.flags |= Update;
1344-
}
1347+
const retryQueue: RetryQueue | null =
1348+
(suspended.updateQueue: any);
1349+
workInProgress.updateQueue = retryQueue;
1350+
scheduleRetryEffect(workInProgress, retryQueue);
13451351

13461352
// Rerender the whole list, but this time, we'll force fallbacks
13471353
// to stay in place.
@@ -1399,11 +1405,9 @@ function completeWork(
13991405

14001406
// Ensure we transfer the update queue to the parent so that it doesn't
14011407
// get lost if this row ends up dropped during a second pass.
1402-
const newThenables = suspended.updateQueue;
1403-
if (newThenables !== null) {
1404-
workInProgress.updateQueue = newThenables;
1405-
workInProgress.flags |= Update;
1406-
}
1408+
const retryQueue: RetryQueue | null = (suspended.updateQueue: any);
1409+
workInProgress.updateQueue = retryQueue;
1410+
scheduleRetryEffect(workInProgress, retryQueue);
14071411

14081412
cutOffTailIfNeeded(renderState, true);
14091413
// This might have been modified.
@@ -1566,10 +1570,11 @@ function completeWork(
15661570
}
15671571
}
15681572

1569-
if (workInProgress.updateQueue !== null) {
1570-
// Schedule an effect to attach Suspense retry listeners
1571-
// TODO: Move to passive phase
1572-
workInProgress.flags |= Update;
1573+
const offscreenQueue: OffscreenQueue | null =
1574+
(workInProgress.updateQueue: any);
1575+
if (offscreenQueue !== null) {
1576+
const retryQueue = offscreenQueue.retryQueue;
1577+
scheduleRetryEffect(workInProgress, retryQueue);
15731578
}
15741579

15751580
if (enableCache) {

packages/react-reconciler/src/ReactFiberOffscreenComponent.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import type {
1515
Transition,
1616
TracingMarkerInstance,
1717
} from './ReactFiberTracingMarkerComponent';
18+
import type {RetryQueue} from './ReactFiberSuspenseComponent';
1819

1920
export type OffscreenProps = {
2021
// TODO: Pick an API before exposing the Offscreen type. I've chosen an enum
@@ -40,7 +41,7 @@ export type OffscreenState = {
4041
export type OffscreenQueue = {
4142
transitions: Array<Transition> | null,
4243
markerInstances: Array<TracingMarkerInstance> | null,
43-
wakeables: Set<Wakeable> | null,
44+
retryQueue: RetryQueue | null,
4445
};
4546

4647
type OffscreenVisibility = number;

packages/react-reconciler/src/ReactFiberSuspenseComponent.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ export type SuspenseListRenderState = {
6767
tailMode: SuspenseListTailMode,
6868
};
6969

70+
export type RetryQueue = Set<Wakeable>;
71+
7072
export function findFirstSuspended(row: Fiber): null | Fiber {
7173
let node = row;
7274
while (node !== null) {

packages/react-reconciler/src/ReactFiberThrow.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type {CapturedValue} from './ReactCapturedValue';
1313
import type {Update} from './ReactFiberClassUpdateQueue';
1414
import type {Wakeable} from 'shared/ReactTypes';
1515
import type {OffscreenQueue} from './ReactFiberOffscreenComponent';
16+
import type {RetryQueue} from './ReactFiberSuspenseComponent';
1617

1718
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
1819
import {
@@ -412,12 +413,12 @@ function throwException(
412413
//
413414
// When the wakeable resolves, we'll attempt to render the boundary
414415
// again ("retry").
415-
const wakeables: Set<Wakeable> | null =
416+
const retryQueue: RetryQueue | null =
416417
(suspenseBoundary.updateQueue: any);
417-
if (wakeables === null) {
418+
if (retryQueue === null) {
418419
suspenseBoundary.updateQueue = new Set([wakeable]);
419420
} else {
420-
wakeables.add(wakeable);
421+
retryQueue.add(wakeable);
421422
}
422423
break;
423424
}
@@ -430,15 +431,15 @@ function throwException(
430431
const newOffscreenQueue: OffscreenQueue = {
431432
transitions: null,
432433
markerInstances: null,
433-
wakeables: new Set([wakeable]),
434+
retryQueue: new Set([wakeable]),
434435
};
435436
suspenseBoundary.updateQueue = newOffscreenQueue;
436437
} else {
437-
const wakeables = offscreenQueue.wakeables;
438-
if (wakeables === null) {
439-
offscreenQueue.wakeables = new Set([wakeable]);
438+
const retryQueue = offscreenQueue.retryQueue;
439+
if (retryQueue === null) {
440+
offscreenQueue.retryQueue = new Set([wakeable]);
440441
} else {
441-
wakeables.add(wakeable);
442+
retryQueue.add(wakeable);
442443
}
443444
}
444445
break;

0 commit comments

Comments
 (0)