@samitouri / QOS-React-2 / commits / ffb6c6c07b

fix: skip dangerouslySetInnerHtml hydration warning if it's undefined (#18676)

* test: Add failing case for dangerouslySetInnerHtml=undefined * fix: skip dangerouslySetInnerHtml warning if it's undefined * test: add similar test that should trigger the warning * chore: Remove redundant nullish check * Poke yarn_test_www_variant which timed out * test: Add smaller test for innerHTML=string to innerHTML=undefined

Sebastian Silbermann committed Apr 20, 2020 at 19:46 UTC ffb6c6c07b1a6dcabd04b22a6a5afeab96d53ae2
2 files changed +58 -6
packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js
+53
@@ -548,4 +548,57 @@ describe('ReactDOMServerHydration', () => {
548 expect(ref.current).toBe(div);
549 expect(element.innerHTML).toBe('<div>Hello World</div>');
550 });
551 +
552 + // regression test for https://github.com/facebook/react/issues/17170
553 + it('should not warn if dangerouslySetInnerHtml=undefined', () => {
554 + const domElement = document.createElement('div');
555 + const reactElement = (
556 + <div dangerouslySetInnerHTML={undefined}>
557 + <p>Hello, World!</p>
558 + </div>
559 + );
560 + const markup = ReactDOMServer.renderToStaticMarkup(reactElement);
561 + domElement.innerHTML = markup;
562 +
563 + ReactDOM.hydrate(reactElement, domElement);
564 +
565 + expect(domElement.innerHTML).toEqual(markup);
566 + });
567 +
568 + it('should warn if innerHTML mismatches with dangerouslySetInnerHTML=undefined and children on the client', () => {
569 + const domElement = document.createElement('div');
570 + const markup = ReactDOMServer.renderToStaticMarkup(
571 + <div dangerouslySetInnerHTML={{__html: '<p>server</p>'}} />,
572 + );
573 + domElement.innerHTML = markup;
574 +
575 + expect(() => {
576 + ReactDOM.hydrate(
577 + <div dangerouslySetInnerHTML={undefined}>
578 + <p>client</p>
579 + </div>,
580 + domElement,
581 + );
582 +
583 + expect(domElement.innerHTML).not.toEqual(markup);
584 + }).toErrorDev(
585 + 'Warning: Text content did not match. Server: "server" Client: "client"',
586 + );
587 + });
588 +
589 + it('should warn if innerHTML mismatches with dangerouslySetInnerHTML=undefined on the client', () => {
590 + const domElement = document.createElement('div');
591 + const markup = ReactDOMServer.renderToStaticMarkup(
592 + <div dangerouslySetInnerHTML={{__html: '<p>server</p>'}} />,
593 + );
594 + domElement.innerHTML = markup;
595 +
596 + expect(() => {
597 + ReactDOM.hydrate(<div dangerouslySetInnerHTML={undefined} />, domElement);
598 +
599 + expect(domElement.innerHTML).not.toEqual(markup);
600 + }).toErrorDev(
601 + 'Warning: Did not expect server HTML to contain a <p> in <div>',
602 + );
603 + });
604 });
packages/react-dom/src/client/ReactDOMComponent.js
+5 -6
@@ -1110,12 +1110,11 @@ export function diffHydratedProperties(
1110 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
1111 const serverHTML = domElement.innerHTML;
1112 const nextHtml = nextProp ? nextProp[HTML] : undefined;
1113 - const expectedHTML = normalizeHTML(
1114 - domElement,
1115 - nextHtml != null ? nextHtml : '',
1116 - );
1117 - if (expectedHTML !== serverHTML) {
1118 - warnForPropDifference(propKey, serverHTML, expectedHTML);
1113 + if (nextHtml != null) {
1114 + const expectedHTML = normalizeHTML(domElement, nextHtml);
1115 + if (expectedHTML !== serverHTML) {
1116 + warnForPropDifference(propKey, serverHTML, expectedHTML);
1117 + }
1118 }
1119 } else if (propKey === STYLE) {
1120 // $FlowFixMe - Should be inferred as not undefined.