Skip to content

Commit 4e244c8

Browse files
committed
Mark boundaries in future rows as postponed
1 parent 8eb465f commit 4e244c8

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

packages/react-dom/src/__tests__/ReactDOMFizzStaticBrowser-test.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2262,6 +2262,7 @@ describe('ReactDOMFizzStaticBrowser', () => {
22622262
<ComponentB />
22632263
</Suspense>
22642264
<Suspense fallback="Loading C">C</Suspense>
2265+
<Suspense fallback="Loading D">D</Suspense>
22652266
</SuspenseList>
22662267
</div>
22672268
);
@@ -2282,14 +2283,16 @@ describe('ReactDOMFizzStaticBrowser', () => {
22822283
});
22832284

22842285
const prerendered = await pendingResult;
2286+
22852287
const postponedState = JSON.stringify(prerendered.postponed);
22862288

22872289
await readIntoContainer(prerendered.prelude);
22882290
expect(getVisibleChildren(container)).toEqual(
22892291
<div>
22902292
{'Loading A'}
22912293
{'Loading B'}
2292-
{'C' /* TODO: This should not be resolved. */}
2294+
{'Loading C'}
2295+
{'Loading D'}
22932296
</div>,
22942297
);
22952298

@@ -2309,6 +2312,7 @@ describe('ReactDOMFizzStaticBrowser', () => {
23092312
{'A'}
23102313
{'B'}
23112314
{'C'}
2315+
{'D'}
23122316
</div>,
23132317
);
23142318
});

packages/react-server/src/ReactFizzServer.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,6 +1725,26 @@ function unblockSuspenseListRow(
17251725
}
17261726
}
17271727

1728+
function trackPostponedSuspenseListRow(
1729+
request: Request,
1730+
trackedPostpones: PostponedHoles,
1731+
postponedRow: null | SuspenseListRow,
1732+
): void {
1733+
// TODO: Because we unconditionally call this, it will be called by finishedTask
1734+
// and so ends up recursive which can lead to stack overflow for very long lists.
1735+
if (postponedRow !== null) {
1736+
const postponedBoundaries = postponedRow.boundaries;
1737+
if (postponedBoundaries !== null) {
1738+
postponedRow.boundaries = null;
1739+
for (let i = 0; i < postponedBoundaries.length; i++) {
1740+
const postponedBoundary = postponedBoundaries[i];
1741+
trackPostponedBoundary(request, trackedPostpones, postponedBoundary);
1742+
finishedTask(request, postponedBoundary, null, null);
1743+
}
1744+
}
1745+
}
1746+
}
1747+
17281748
function tryToResolveTogetherRow(
17291749
request: Request,
17301750
togetherRow: SuspenseListRow,
@@ -4945,7 +4965,18 @@ function finishedTask(
49454965
} else if (boundary.status === POSTPONED) {
49464966
const boundaryRow = boundary.row;
49474967
if (boundaryRow !== null) {
4968+
if (request.trackedPostpones !== null) {
4969+
// If this boundary is postponed, then we need to also postpone any blocked boundaries
4970+
// in the next row.
4971+
trackPostponedSuspenseListRow(
4972+
request,
4973+
request.trackedPostpones,
4974+
boundaryRow.next,
4975+
);
4976+
}
49484977
if (--boundaryRow.pendingTasks === 0) {
4978+
// This is really unnecessary since we've already postponed the boundaries but
4979+
// for pairity with other track+finish paths. We might end up using the hoisting.
49494980
finishSuspenseListRow(request, boundaryRow);
49504981
}
49514982
}

0 commit comments

Comments
 (0)