Skip to content

Commit c11b196

Browse files
authored
Move tail hydration mismatch back to hydration context (#28501)
In #23176 we added a special case in completeWork for SuspenseBoundaries if they still have trailing children. However, that misses a case because it doesn't log a recoverable error for the hydration mismatch. So we get an error that we rerendered. I think this special case was done to avoid contexts getting out of sync. I don't know why we didn't just move where the pop happens though so that's what I did here and let the regular pass throw instead. Seems to be pass the tests.
1 parent 966d174 commit c11b196

File tree

3 files changed

+5
-21
lines changed

3 files changed

+5
-21
lines changed

packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js

+1
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,7 @@ describe('ReactDOMServerPartialHydration', () => {
538538
assertLog([
539539
'Server rendered',
540540
'Client rendered',
541+
'Hydration failed because the initial UI does not match what was rendered on the server.',
541542
'There was an error while hydrating this Suspense boundary. ' +
542543
'Switched to client rendering.',
543544
]);

packages/react-reconciler/src/ReactFiberCompleteWork.js

+4-15
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,9 @@ import {
141141
prepareToHydrateHostInstance,
142142
prepareToHydrateHostTextInstance,
143143
prepareToHydrateHostSuspenseInstance,
144-
warnIfUnhydratedTailNodes,
145144
popHydrationState,
146145
resetHydrationState,
147146
getIsHydrating,
148-
hasUnhydratedTailNodes,
149147
upgradeHydrationErrorsToRecoverable,
150148
} from './ReactFiberHydrationContext';
151149
import {
@@ -866,18 +864,6 @@ function completeDehydratedSuspenseBoundary(
866864
workInProgress: Fiber,
867865
nextState: SuspenseState | null,
868866
): boolean {
869-
if (
870-
hasUnhydratedTailNodes() &&
871-
(workInProgress.mode & ConcurrentMode) !== NoMode &&
872-
(workInProgress.flags & DidCapture) === NoFlags
873-
) {
874-
warnIfUnhydratedTailNodes(workInProgress);
875-
resetHydrationState();
876-
workInProgress.flags |= ForceClientRender | DidCapture;
877-
878-
return false;
879-
}
880-
881867
const wasHydrated = popHydrationState(workInProgress);
882868

883869
if (nextState !== null && nextState.dehydrated !== null) {
@@ -1337,7 +1323,6 @@ function completeWork(
13371323
return null;
13381324
}
13391325
case SuspenseComponent: {
1340-
popSuspenseHandler(workInProgress);
13411326
const nextState: null | SuspenseState = workInProgress.memoizedState;
13421327

13431328
// Special path for dehydrated boundaries. We may eventually move this
@@ -1358,10 +1343,12 @@ function completeWork(
13581343
);
13591344
if (!fallthroughToNormalSuspensePath) {
13601345
if (workInProgress.flags & ForceClientRender) {
1346+
popSuspenseHandler(workInProgress);
13611347
// Special case. There were remaining unhydrated nodes. We treat
13621348
// this as a mismatch. Revert to client rendering.
13631349
return workInProgress;
13641350
} else {
1351+
popSuspenseHandler(workInProgress);
13651352
// Did not finish hydrating, either because this is the initial
13661353
// render or because something suspended.
13671354
return null;
@@ -1371,6 +1358,8 @@ function completeWork(
13711358
// Continue with the normal Suspense path.
13721359
}
13731360

1361+
popSuspenseHandler(workInProgress);
1362+
13741363
if ((workInProgress.flags & DidCapture) !== NoFlags) {
13751364
// Something suspended. Re-render with the fallback children.
13761365
workInProgress.lanes = renderLanes;

packages/react-reconciler/src/ReactFiberHydrationContext.js

-6
Original file line numberDiff line numberDiff line change
@@ -893,10 +893,6 @@ function popHydrationState(fiber: Fiber): boolean {
893893
return true;
894894
}
895895

896-
function hasUnhydratedTailNodes(): boolean {
897-
return isHydrating && nextHydratableInstance !== null;
898-
}
899-
900896
function warnIfUnhydratedTailNodes(fiber: Fiber) {
901897
let nextInstance = nextHydratableInstance;
902898
while (nextInstance) {
@@ -952,6 +948,4 @@ export {
952948
prepareToHydrateHostTextInstance,
953949
prepareToHydrateHostSuspenseInstance,
954950
popHydrationState,
955-
hasUnhydratedTailNodes,
956-
warnIfUnhydratedTailNodes,
957951
};

0 commit comments

Comments
 (0)