diff --git a/packages/react-dom-bindings/src/client/ReactDOMComponent.js b/packages/react-dom-bindings/src/client/ReactDOMComponent.js index 1b25e3727023..8a5058128199 100644 --- a/packages/react-dom-bindings/src/client/ReactDOMComponent.js +++ b/packages/react-dom-bindings/src/client/ReactDOMComponent.js @@ -2618,6 +2618,10 @@ function diffHydratedGenericElement( // Noop continue; case 'dangerouslySetInnerHTML': + // Skip innerHTML comparison only when suppressHydrationWarning is also set + if (props.suppressHydrationWarning === true) { + continue; + } const serverHTML = domElement.innerHTML; const nextHtml = value ? value.__html : undefined; if (nextHtml != null) { @@ -3220,10 +3224,12 @@ export function hydrateProperties( // even listeners these nodes might be wired up to. // TODO: Warn if there is more than a single textNode as a child. // TODO: Should we use domElement.firstChild.nodeValue to compare? + // Skip text content check if both dangerouslySetInnerHTML and suppressHydrationWarning are present if ( - typeof children === 'string' || - typeof children === 'number' || - typeof children === 'bigint' + !(props.dangerouslySetInnerHTML != null && props.suppressHydrationWarning === true) && + (typeof children === 'string' || + typeof children === 'number' || + typeof children === 'bigint') ) { if ( // $FlowFixMe[unsafe-addition] Flow doesn't want us to use `+` operator with string and bigint diff --git a/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js b/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js index 5675c7eb0e73..9b3120160730 100644 --- a/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js +++ b/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js @@ -802,4 +802,46 @@ describe('ReactDOMServerHydration', () => { expect(ref.current).toBe(button); }); + + it('should skip hydration of elements with dangerouslySetInnerHTML and suppressHydrationWarning', async () => { + const htmlContent = { + __html: '
This is HTML content
', + }; + + function TestComponent() { + return ( +Footer
+This is HTML content
', + ); + + // change content before hydration to simulate a mismatch + testElement.innerHTML = '