diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
index 75a821b224d06..6a5ba954bda3f 100644
--- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
@@ -1447,4 +1447,35 @@ describe('ReactDOMFizzServer', () => {
expect(loggedErrors).toEqual([theError]);
});
+
+ // @gate experimental
+ it('should be able to abort the fallback if the main content finishes first', async () => {
+ await act(async () => {
+ const {startWriting} = ReactDOMFizzServer.pipeToNodeWritable(
+ }>
+
+ }>
+
+
+
+ ,
+ writable,
+ );
+ startWriting();
+ });
+ expect(getVisibleChildren(container)).toEqual('Loading Outer');
+ // We should have received a partial segment containing the a partial of the fallback.
+ expect(container.innerHTML).toContain('Inner');
+ await act(async () => {
+ resolveText('Hello');
+ });
+ // We should've been able to display the content without waiting for the rest of the fallback.
+ expect(getVisibleChildren(container)).toEqual(Hello
);
+ });
});
diff --git a/packages/react-server/src/ReactFizzServer.js b/packages/react-server/src/ReactFizzServer.js
index 47a0d23fd7381..4b7eb46d94b48 100644
--- a/packages/react-server/src/ReactFizzServer.js
+++ b/packages/react-server/src/ReactFizzServer.js
@@ -1408,7 +1408,11 @@ function finishedTask(
// This must have been the last segment we were waiting on. This boundary is now complete.
if (segment.parentFlushed) {
// Our parent segment already flushed, so we need to schedule this segment to be emitted.
- boundary.completedSegments.push(segment);
+ // If it is a segment that was aborted, we'll write other content instead so we don't need
+ // to emit it.
+ if (segment.status === COMPLETED) {
+ boundary.completedSegments.push(segment);
+ }
}
if (boundary.parentFlushed) {
// The segment might be part of a segment that didn't flush yet, but if the boundary's
@@ -1423,14 +1427,18 @@ function finishedTask(
} else {
if (segment.parentFlushed) {
// Our parent already flushed, so we need to schedule this segment to be emitted.
- const completedSegments = boundary.completedSegments;
- completedSegments.push(segment);
- if (completedSegments.length === 1) {
- // This is the first time since we last flushed that we completed anything.
- // We can schedule this boundary to emit its partially completed segments early
- // in case the parent has already been flushed.
- if (boundary.parentFlushed) {
- request.partialBoundaries.push(boundary);
+ // If it is a segment that was aborted, we'll write other content instead so we don't need
+ // to emit it.
+ if (segment.status === COMPLETED) {
+ const completedSegments = boundary.completedSegments;
+ completedSegments.push(segment);
+ if (completedSegments.length === 1) {
+ // This is the first time since we last flushed that we completed anything.
+ // We can schedule this boundary to emit its partially completed segments early
+ // in case the parent has already been flushed.
+ if (boundary.parentFlushed) {
+ request.partialBoundaries.push(boundary);
+ }
}
}
}
@@ -1570,7 +1578,7 @@ function flushSubtree(
default: {
invariant(
false,
- 'Errored or already flushed boundaries should not be flushed again. This is a bug in React.',
+ 'Aborted, errored or already flushed boundaries should not be flushed again. This is a bug in React.',
);
}
}
diff --git a/scripts/error-codes/codes.json b/scripts/error-codes/codes.json
index 38de792d6998c..950598f4c71fc 100644
--- a/scripts/error-codes/codes.json
+++ b/scripts/error-codes/codes.json
@@ -378,7 +378,7 @@
"387": "Should have a current fiber. This is a bug in React.",
"388": "Expected to find a bailed out fiber. This is a bug in React.",
"389": "There can only be one root segment. This is a bug in React.",
- "390": "Errored or already flushed boundaries should not be flushed again. This is a bug in React.",
+ "390": "Aborted, errored or already flushed boundaries should not be flushed again. This is a bug in React.",
"391": "A previously unvisited boundary must have exactly one root segment. This is a bug in React.",
"392": "A root segment ID must have been assigned by now. This is a bug in React.",
"393": "Cache cannot be refreshed during server rendering.",