mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Don't mute hydration errors forcing client render (#24276)
* Don't mute hydration errors forcing client render * Nits
This commit is contained in:
+14
-7
@@ -248,9 +248,10 @@ describe('ReactDOMFizzServerHydrationWarning', () => {
|
||||
]);
|
||||
}).toErrorDev(
|
||||
[
|
||||
'Expected server HTML to contain a matching <span> in <span>',
|
||||
'An error occurred during hydration. The server HTML was replaced with client content in <div>.',
|
||||
],
|
||||
{withoutStack: true},
|
||||
{withoutStack: 1},
|
||||
);
|
||||
} else {
|
||||
// This used to not warn.
|
||||
@@ -336,9 +337,10 @@ describe('ReactDOMFizzServerHydrationWarning', () => {
|
||||
]);
|
||||
}).toErrorDev(
|
||||
[
|
||||
'Did not expect server HTML to contain the text node "Server" in <span>',
|
||||
'An error occurred during hydration. The server HTML was replaced with client content in <div>.',
|
||||
],
|
||||
{withoutStack: true},
|
||||
{withoutStack: 1},
|
||||
);
|
||||
} else {
|
||||
// This used to not warn.
|
||||
@@ -389,9 +391,10 @@ describe('ReactDOMFizzServerHydrationWarning', () => {
|
||||
]);
|
||||
}).toErrorDev(
|
||||
[
|
||||
'Expected server HTML to contain a matching text node for "Client" in <span>.',
|
||||
'An error occurred during hydration. The server HTML was replaced with client content in <div>.',
|
||||
],
|
||||
{withoutStack: true},
|
||||
{withoutStack: 1},
|
||||
);
|
||||
} else {
|
||||
// This used to not warn.
|
||||
@@ -445,9 +448,10 @@ describe('ReactDOMFizzServerHydrationWarning', () => {
|
||||
]);
|
||||
}).toErrorDev(
|
||||
[
|
||||
'Did not expect server HTML to contain the text node "Server" in <span>.',
|
||||
'An error occurred during hydration. The server HTML was replaced with client content in <div>.',
|
||||
],
|
||||
{withoutStack: true},
|
||||
{withoutStack: 1},
|
||||
);
|
||||
} else {
|
||||
// This used to not warn.
|
||||
@@ -500,9 +504,10 @@ describe('ReactDOMFizzServerHydrationWarning', () => {
|
||||
]);
|
||||
}).toErrorDev(
|
||||
[
|
||||
'Expected server HTML to contain a matching text node for "Client" in <span>.',
|
||||
'An error occurred during hydration. The server HTML was replaced with client content in <div>.',
|
||||
],
|
||||
{withoutStack: true},
|
||||
{withoutStack: 1},
|
||||
);
|
||||
} else {
|
||||
// This used to not warn.
|
||||
@@ -630,9 +635,10 @@ describe('ReactDOMFizzServerHydrationWarning', () => {
|
||||
]);
|
||||
}).toErrorDev(
|
||||
[
|
||||
'Expected server HTML to contain a matching <p> in <div>.',
|
||||
'An error occurred during hydration. The server HTML was replaced with client content in <div>.',
|
||||
],
|
||||
{withoutStack: true},
|
||||
{withoutStack: 1},
|
||||
);
|
||||
} else {
|
||||
// This used to not warn.
|
||||
@@ -681,9 +687,10 @@ describe('ReactDOMFizzServerHydrationWarning', () => {
|
||||
]);
|
||||
}).toErrorDev(
|
||||
[
|
||||
'Did not expect server HTML to contain a <p> in <div>.',
|
||||
'An error occurred during hydration. The server HTML was replaced with client content in <div>.',
|
||||
],
|
||||
{withoutStack: true},
|
||||
{withoutStack: 1},
|
||||
);
|
||||
} else {
|
||||
// This used to not warn.
|
||||
|
||||
+31
-12
@@ -62,6 +62,7 @@ import dangerousStyleValue from '../shared/dangerousStyleValue';
|
||||
import {retryIfBlockedOn} from '../events/ReactDOMEventReplaying';
|
||||
|
||||
import {
|
||||
enableClientRenderFallbackOnHydrationMismatch,
|
||||
enableSuspenseServerRenderer,
|
||||
enableCreateEventHandleAPI,
|
||||
enableScopeAPI,
|
||||
@@ -1004,14 +1005,20 @@ export function didNotHydrateInstance(
|
||||
parentProps: Props,
|
||||
parentInstance: Instance,
|
||||
instance: HydratableInstance,
|
||||
isConcurrentMode: boolean,
|
||||
) {
|
||||
if (__DEV__ && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
|
||||
if (instance.nodeType === ELEMENT_NODE) {
|
||||
warnForDeletedHydratableElement(parentInstance, (instance: any));
|
||||
} else if (instance.nodeType === COMMENT_NODE) {
|
||||
// TODO: warnForDeletedHydratableSuspenseBoundary
|
||||
} else {
|
||||
warnForDeletedHydratableText(parentInstance, (instance: any));
|
||||
if (__DEV__) {
|
||||
if (
|
||||
(enableClientRenderFallbackOnHydrationMismatch && isConcurrentMode) ||
|
||||
parentProps[SUPPRESS_HYDRATION_WARNING] !== true
|
||||
) {
|
||||
if (instance.nodeType === ELEMENT_NODE) {
|
||||
warnForDeletedHydratableElement(parentInstance, (instance: any));
|
||||
} else if (instance.nodeType === COMMENT_NODE) {
|
||||
// TODO: warnForDeletedHydratableSuspenseBoundary
|
||||
} else {
|
||||
warnForDeletedHydratableText(parentInstance, (instance: any));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1082,9 +1089,15 @@ export function didNotFindHydratableInstance(
|
||||
parentInstance: Instance,
|
||||
type: string,
|
||||
props: Props,
|
||||
isConcurrentMode: boolean,
|
||||
) {
|
||||
if (__DEV__ && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
|
||||
warnForInsertedHydratedElement(parentInstance, type, props);
|
||||
if (__DEV__) {
|
||||
if (
|
||||
(enableClientRenderFallbackOnHydrationMismatch && isConcurrentMode) ||
|
||||
parentProps[SUPPRESS_HYDRATION_WARNING] !== true
|
||||
) {
|
||||
warnForInsertedHydratedElement(parentInstance, type, props);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1093,9 +1106,15 @@ export function didNotFindHydratableTextInstance(
|
||||
parentProps: Props,
|
||||
parentInstance: Instance,
|
||||
text: string,
|
||||
isConcurrentMode: boolean,
|
||||
) {
|
||||
if (__DEV__ && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
|
||||
warnForInsertedHydratedText(parentInstance, text);
|
||||
if (__DEV__) {
|
||||
if (
|
||||
(enableClientRenderFallbackOnHydrationMismatch && isConcurrentMode) ||
|
||||
parentProps[SUPPRESS_HYDRATION_WARNING] !== true
|
||||
) {
|
||||
warnForInsertedHydratedText(parentInstance, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1104,7 +1123,7 @@ export function didNotFindHydratableSuspenseInstance(
|
||||
parentProps: Props,
|
||||
parentInstance: Instance,
|
||||
) {
|
||||
if (__DEV__ && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
|
||||
if (__DEV__) {
|
||||
// TODO: warnForInsertedHydratedSuspense(parentInstance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,21 +148,26 @@ function warnUnhydratedInstance(
|
||||
) {
|
||||
if (__DEV__) {
|
||||
switch (returnFiber.tag) {
|
||||
case HostRoot:
|
||||
case HostRoot: {
|
||||
didNotHydrateInstanceWithinContainer(
|
||||
returnFiber.stateNode.containerInfo,
|
||||
instance,
|
||||
);
|
||||
break;
|
||||
case HostComponent:
|
||||
}
|
||||
case HostComponent: {
|
||||
const isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
|
||||
didNotHydrateInstance(
|
||||
returnFiber.type,
|
||||
returnFiber.memoizedProps,
|
||||
returnFiber.stateNode,
|
||||
instance,
|
||||
// TODO: Delete this argument when we remove the legacy root API.
|
||||
isConcurrentMode,
|
||||
);
|
||||
break;
|
||||
case SuspenseComponent:
|
||||
}
|
||||
case SuspenseComponent: {
|
||||
const suspenseState: SuspenseState = returnFiber.memoizedState;
|
||||
if (suspenseState.dehydrated !== null)
|
||||
didNotHydrateInstanceWithinSuspenseInstance(
|
||||
@@ -170,6 +175,7 @@ function warnUnhydratedInstance(
|
||||
instance,
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -234,33 +240,44 @@ function warnNonhydratedInstance(returnFiber: Fiber, fiber: Fiber) {
|
||||
const parentProps = returnFiber.memoizedProps;
|
||||
const parentInstance = returnFiber.stateNode;
|
||||
switch (fiber.tag) {
|
||||
case HostComponent:
|
||||
case HostComponent: {
|
||||
const type = fiber.type;
|
||||
const props = fiber.pendingProps;
|
||||
const isConcurrentMode =
|
||||
(returnFiber.mode & ConcurrentMode) !== NoMode;
|
||||
didNotFindHydratableInstance(
|
||||
parentType,
|
||||
parentProps,
|
||||
parentInstance,
|
||||
type,
|
||||
props,
|
||||
// TODO: Delete this argument when we remove the legacy root API.
|
||||
isConcurrentMode,
|
||||
);
|
||||
break;
|
||||
case HostText:
|
||||
}
|
||||
case HostText: {
|
||||
const text = fiber.pendingProps;
|
||||
const isConcurrentMode =
|
||||
(returnFiber.mode & ConcurrentMode) !== NoMode;
|
||||
didNotFindHydratableTextInstance(
|
||||
parentType,
|
||||
parentProps,
|
||||
parentInstance,
|
||||
text,
|
||||
// TODO: Delete this argument when we remove the legacy root API.
|
||||
isConcurrentMode,
|
||||
);
|
||||
break;
|
||||
case SuspenseComponent:
|
||||
}
|
||||
case SuspenseComponent: {
|
||||
didNotFindHydratableSuspenseInstance(
|
||||
parentType,
|
||||
parentProps,
|
||||
parentInstance,
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -476,10 +493,11 @@ function prepareToHydrateHostTextInstance(fiber: Fiber): boolean {
|
||||
// hydration parent is the parent host component of this host text.
|
||||
const returnFiber = hydrationParentFiber;
|
||||
if (returnFiber !== null) {
|
||||
const isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
|
||||
switch (returnFiber.tag) {
|
||||
case HostRoot: {
|
||||
const parentContainer = returnFiber.stateNode.containerInfo;
|
||||
const isConcurrentMode =
|
||||
(returnFiber.mode & ConcurrentMode) !== NoMode;
|
||||
didNotMatchHydratedContainerTextInstance(
|
||||
parentContainer,
|
||||
textInstance,
|
||||
@@ -493,6 +511,8 @@ function prepareToHydrateHostTextInstance(fiber: Fiber): boolean {
|
||||
const parentType = returnFiber.type;
|
||||
const parentProps = returnFiber.memoizedProps;
|
||||
const parentInstance = returnFiber.stateNode;
|
||||
const isConcurrentMode =
|
||||
(returnFiber.mode & ConcurrentMode) !== NoMode;
|
||||
didNotMatchHydratedTextInstance(
|
||||
parentType,
|
||||
parentProps,
|
||||
|
||||
@@ -148,21 +148,26 @@ function warnUnhydratedInstance(
|
||||
) {
|
||||
if (__DEV__) {
|
||||
switch (returnFiber.tag) {
|
||||
case HostRoot:
|
||||
case HostRoot: {
|
||||
didNotHydrateInstanceWithinContainer(
|
||||
returnFiber.stateNode.containerInfo,
|
||||
instance,
|
||||
);
|
||||
break;
|
||||
case HostComponent:
|
||||
}
|
||||
case HostComponent: {
|
||||
const isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
|
||||
didNotHydrateInstance(
|
||||
returnFiber.type,
|
||||
returnFiber.memoizedProps,
|
||||
returnFiber.stateNode,
|
||||
instance,
|
||||
// TODO: Delete this argument when we remove the legacy root API.
|
||||
isConcurrentMode,
|
||||
);
|
||||
break;
|
||||
case SuspenseComponent:
|
||||
}
|
||||
case SuspenseComponent: {
|
||||
const suspenseState: SuspenseState = returnFiber.memoizedState;
|
||||
if (suspenseState.dehydrated !== null)
|
||||
didNotHydrateInstanceWithinSuspenseInstance(
|
||||
@@ -170,6 +175,7 @@ function warnUnhydratedInstance(
|
||||
instance,
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -234,33 +240,44 @@ function warnNonhydratedInstance(returnFiber: Fiber, fiber: Fiber) {
|
||||
const parentProps = returnFiber.memoizedProps;
|
||||
const parentInstance = returnFiber.stateNode;
|
||||
switch (fiber.tag) {
|
||||
case HostComponent:
|
||||
case HostComponent: {
|
||||
const type = fiber.type;
|
||||
const props = fiber.pendingProps;
|
||||
const isConcurrentMode =
|
||||
(returnFiber.mode & ConcurrentMode) !== NoMode;
|
||||
didNotFindHydratableInstance(
|
||||
parentType,
|
||||
parentProps,
|
||||
parentInstance,
|
||||
type,
|
||||
props,
|
||||
// TODO: Delete this argument when we remove the legacy root API.
|
||||
isConcurrentMode,
|
||||
);
|
||||
break;
|
||||
case HostText:
|
||||
}
|
||||
case HostText: {
|
||||
const text = fiber.pendingProps;
|
||||
const isConcurrentMode =
|
||||
(returnFiber.mode & ConcurrentMode) !== NoMode;
|
||||
didNotFindHydratableTextInstance(
|
||||
parentType,
|
||||
parentProps,
|
||||
parentInstance,
|
||||
text,
|
||||
// TODO: Delete this argument when we remove the legacy root API.
|
||||
isConcurrentMode,
|
||||
);
|
||||
break;
|
||||
case SuspenseComponent:
|
||||
}
|
||||
case SuspenseComponent: {
|
||||
didNotFindHydratableSuspenseInstance(
|
||||
parentType,
|
||||
parentProps,
|
||||
parentInstance,
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -476,10 +493,11 @@ function prepareToHydrateHostTextInstance(fiber: Fiber): boolean {
|
||||
// hydration parent is the parent host component of this host text.
|
||||
const returnFiber = hydrationParentFiber;
|
||||
if (returnFiber !== null) {
|
||||
const isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
|
||||
switch (returnFiber.tag) {
|
||||
case HostRoot: {
|
||||
const parentContainer = returnFiber.stateNode.containerInfo;
|
||||
const isConcurrentMode =
|
||||
(returnFiber.mode & ConcurrentMode) !== NoMode;
|
||||
didNotMatchHydratedContainerTextInstance(
|
||||
parentContainer,
|
||||
textInstance,
|
||||
@@ -493,6 +511,8 @@ function prepareToHydrateHostTextInstance(fiber: Fiber): boolean {
|
||||
const parentType = returnFiber.type;
|
||||
const parentProps = returnFiber.memoizedProps;
|
||||
const parentInstance = returnFiber.stateNode;
|
||||
const isConcurrentMode =
|
||||
(returnFiber.mode & ConcurrentMode) !== NoMode;
|
||||
didNotMatchHydratedTextInstance(
|
||||
parentType,
|
||||
parentProps,
|
||||
|
||||
Reference in New Issue
Block a user