[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
This commit is contained in:
Sebastian Markbåge 2021-07-27 21:53:37 -04:00 committed by GitHub
parent cdccdbe171
commit 321087d134
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 11 deletions

View File

@ -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(
<Suspense fallback={<Text text="Loading Outer" />}>
<div>
<Suspense
fallback={
<div>
<AsyncText text="Loading" />
Inner
</div>
}>
<AsyncText text="Hello" />
</Suspense>
</div>
</Suspense>,
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(<div>Hello</div>);
});
});

View File

@ -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.',
);
}
}

View File

@ -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.",