Skip to content

Commit 321087d

Browse files
authored
[Fizz] Don't add aborted segments to the completedSegments list (#21976)
* Don't add aborted segments to the completedSegments list * Update error message to include aborted status
1 parent cdccdbe commit 321087d

File tree

3 files changed

+50
-11
lines changed

3 files changed

+50
-11
lines changed

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

+31
Original file line numberDiff line numberDiff line change
@@ -1447,4 +1447,35 @@ describe('ReactDOMFizzServer', () => {
14471447

14481448
expect(loggedErrors).toEqual([theError]);
14491449
});
1450+
1451+
// @gate experimental
1452+
it('should be able to abort the fallback if the main content finishes first', async () => {
1453+
await act(async () => {
1454+
const {startWriting} = ReactDOMFizzServer.pipeToNodeWritable(
1455+
<Suspense fallback={<Text text="Loading Outer" />}>
1456+
<div>
1457+
<Suspense
1458+
fallback={
1459+
<div>
1460+
<AsyncText text="Loading" />
1461+
Inner
1462+
</div>
1463+
}>
1464+
<AsyncText text="Hello" />
1465+
</Suspense>
1466+
</div>
1467+
</Suspense>,
1468+
writable,
1469+
);
1470+
startWriting();
1471+
});
1472+
expect(getVisibleChildren(container)).toEqual('Loading Outer');
1473+
// We should have received a partial segment containing the a partial of the fallback.
1474+
expect(container.innerHTML).toContain('Inner');
1475+
await act(async () => {
1476+
resolveText('Hello');
1477+
});
1478+
// We should've been able to display the content without waiting for the rest of the fallback.
1479+
expect(getVisibleChildren(container)).toEqual(<div>Hello</div>);
1480+
});
14501481
});

packages/react-server/src/ReactFizzServer.js

+18-10
Original file line numberDiff line numberDiff line change
@@ -1408,7 +1408,11 @@ function finishedTask(
14081408
// This must have been the last segment we were waiting on. This boundary is now complete.
14091409
if (segment.parentFlushed) {
14101410
// Our parent segment already flushed, so we need to schedule this segment to be emitted.
1411-
boundary.completedSegments.push(segment);
1411+
// If it is a segment that was aborted, we'll write other content instead so we don't need
1412+
// to emit it.
1413+
if (segment.status === COMPLETED) {
1414+
boundary.completedSegments.push(segment);
1415+
}
14121416
}
14131417
if (boundary.parentFlushed) {
14141418
// The segment might be part of a segment that didn't flush yet, but if the boundary's
@@ -1423,14 +1427,18 @@ function finishedTask(
14231427
} else {
14241428
if (segment.parentFlushed) {
14251429
// Our parent already flushed, so we need to schedule this segment to be emitted.
1426-
const completedSegments = boundary.completedSegments;
1427-
completedSegments.push(segment);
1428-
if (completedSegments.length === 1) {
1429-
// This is the first time since we last flushed that we completed anything.
1430-
// We can schedule this boundary to emit its partially completed segments early
1431-
// in case the parent has already been flushed.
1432-
if (boundary.parentFlushed) {
1433-
request.partialBoundaries.push(boundary);
1430+
// If it is a segment that was aborted, we'll write other content instead so we don't need
1431+
// to emit it.
1432+
if (segment.status === COMPLETED) {
1433+
const completedSegments = boundary.completedSegments;
1434+
completedSegments.push(segment);
1435+
if (completedSegments.length === 1) {
1436+
// This is the first time since we last flushed that we completed anything.
1437+
// We can schedule this boundary to emit its partially completed segments early
1438+
// in case the parent has already been flushed.
1439+
if (boundary.parentFlushed) {
1440+
request.partialBoundaries.push(boundary);
1441+
}
14341442
}
14351443
}
14361444
}
@@ -1570,7 +1578,7 @@ function flushSubtree(
15701578
default: {
15711579
invariant(
15721580
false,
1573-
'Errored or already flushed boundaries should not be flushed again. This is a bug in React.',
1581+
'Aborted, errored or already flushed boundaries should not be flushed again. This is a bug in React.',
15741582
);
15751583
}
15761584
}

scripts/error-codes/codes.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@
378378
"387": "Should have a current fiber. This is a bug in React.",
379379
"388": "Expected to find a bailed out fiber. This is a bug in React.",
380380
"389": "There can only be one root segment. This is a bug in React.",
381-
"390": "Errored or already flushed boundaries should not be flushed again. This is a bug in React.",
381+
"390": "Aborted, errored or already flushed boundaries should not be flushed again. This is a bug in React.",
382382
"391": "A previously unvisited boundary must have exactly one root segment. This is a bug in React.",
383383
"392": "A root segment ID must have been assigned by now. This is a bug in React.",
384384
"393": "Cache cannot be refreshed during server rendering.",

0 commit comments

Comments
 (0)