diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
index 295e99b26a691..d4687ab4d365b 100644
--- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
@@ -2811,4 +2811,96 @@ describe('ReactDOMFizzServer', () => {
,
);
});
+
+ // @gate experimental
+ it('suppresses and fixes text mismatches with suppressHydrationWarning', async () => {
+ function App({isClient}) {
+ return (
+
+
+ {isClient ? 'Client Text' : 'Server Text'}
+
+ {isClient ? 2 : 1}
+
+ hello,{isClient ? 'client' : 'server'}
+
+
+ );
+ }
+ await act(async () => {
+ const {pipe} = ReactDOMFizzServer.renderToPipeableStream(
+ ,
+ );
+ pipe(writable);
+ });
+ expect(getVisibleChildren(container)).toEqual(
+
+ Server Text
+ 1
+
+ {'hello,'}
+ {'server'}
+
+
,
+ );
+ ReactDOMClient.hydrateRoot(container, , {
+ onRecoverableError(error) {
+ // Don't miss a hydration error. There should be none.
+ Scheduler.unstable_yieldValue(error.message);
+ },
+ });
+ expect(Scheduler).toFlushAndYield([]);
+ // The text mismatch should be *silently* fixed. Even in production.
+ // The attribute mismatch should be ignored and not fixed.
+ expect(getVisibleChildren(container)).toEqual(
+
+ Client Text
+ 2
+
+ {'hello,'}
+ {'client'}
+
+
,
+ );
+ });
+
+ // @gate experimental
+ it('suppresses and does not fix html mismatches with suppressHydrationWarning', async () => {
+ function App({isClient}) {
+ return (
+
+ );
+ }
+ await act(async () => {
+ const {pipe} = ReactDOMFizzServer.renderToPipeableStream(
+ ,
+ );
+ pipe(writable);
+ });
+ expect(getVisibleChildren(container)).toEqual(
+ ,
+ );
+ ReactDOMClient.hydrateRoot(container, , {
+ onRecoverableError(error) {
+ Scheduler.unstable_yieldValue(error.message);
+ },
+ });
+ expect(Scheduler).toFlushAndYield([]);
+ expect(getVisibleChildren(container)).toEqual(
+ ,
+ );
+ });
});
diff --git a/packages/react-dom/src/client/ReactDOMComponent.js b/packages/react-dom/src/client/ReactDOMComponent.js
index 7f9b6ac47d8a0..75e017a451836 100644
--- a/packages/react-dom/src/client/ReactDOMComponent.js
+++ b/packages/react-dom/src/client/ReactDOMComponent.js
@@ -91,7 +91,6 @@ const STYLE = 'style';
const HTML = '__html';
let warnedUnknownTags;
-let suppressHydrationWarning;
let validatePropertiesInDevelopment;
let warnForPropDifference;
@@ -875,7 +874,6 @@ export function diffHydratedProperties(
let extraAttributeNames: Set;
if (__DEV__) {
- suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING] === true;
isCustomComponentTag = isCustomComponent(tag, rawProps);
validatePropertiesInDevelopment(tag, rawProps);
}
@@ -984,7 +982,7 @@ export function diffHydratedProperties(
// TODO: Should we use domElement.firstChild.nodeValue to compare?
if (typeof nextProp === 'string') {
if (domElement.textContent !== nextProp) {
- if (!suppressHydrationWarning) {
+ if (rawProps[SUPPRESS_HYDRATION_WARNING] !== true) {
checkForUnmatchedText(
domElement.textContent,
nextProp,
@@ -996,7 +994,7 @@ export function diffHydratedProperties(
}
} else if (typeof nextProp === 'number') {
if (domElement.textContent !== '' + nextProp) {
- if (!suppressHydrationWarning) {
+ if (rawProps[SUPPRESS_HYDRATION_WARNING] !== true) {
checkForUnmatchedText(
domElement.textContent,
nextProp,
@@ -1028,7 +1026,7 @@ export function diffHydratedProperties(
isCustomComponentTag && enableCustomElementPropertySupport
? null
: getPropertyInfo(propKey);
- if (suppressHydrationWarning) {
+ if (rawProps[SUPPRESS_HYDRATION_WARNING] === true) {
// Don't bother comparing. We're ignoring all these warnings.
} else if (
propKey === SUPPRESS_CONTENT_EDITABLE_WARNING ||
@@ -1150,8 +1148,11 @@ export function diffHydratedProperties(
if (__DEV__) {
if (shouldWarnDev) {
- // $FlowFixMe - Should be inferred as not undefined.
- if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
+ if (
+ // $FlowFixMe - Should be inferred as not undefined.
+ extraAttributeNames.size > 0 &&
+ rawProps[SUPPRESS_HYDRATION_WARNING] !== true
+ ) {
// $FlowFixMe - Should be inferred as not undefined.
warnForExtraAttributes(extraAttributeNames);
}
diff --git a/packages/react-dom/src/client/ReactDOMHostConfig.js b/packages/react-dom/src/client/ReactDOMHostConfig.js
index 8ded833556c92..925f7088e4b04 100644
--- a/packages/react-dom/src/client/ReactDOMHostConfig.js
+++ b/packages/react-dom/src/client/ReactDOMHostConfig.js
@@ -132,10 +132,7 @@ type SelectionInformation = {|
selectionRange: mixed,
|};
-let SUPPRESS_HYDRATION_WARNING;
-if (__DEV__) {
- SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
-}
+const SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
const SUSPENSE_START_DATA = '$';
const SUSPENSE_END_DATA = '/$';