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
This commit is contained in:
Sebastian Silbermann
2020-04-20 18:46:55 +01:00
committed by GitHub
parent 1078029af6
commit ffb6c6c07b
2 changed files with 58 additions and 6 deletions
@@ -548,4 +548,57 @@ describe('ReactDOMServerHydration', () => {
expect(ref.current).toBe(div);
expect(element.innerHTML).toBe('<div>Hello World</div>');
});
// regression test for https://github.com/facebook/react/issues/17170
it('should not warn if dangerouslySetInnerHtml=undefined', () => {
const domElement = document.createElement('div');
const reactElement = (
<div dangerouslySetInnerHTML={undefined}>
<p>Hello, World!</p>
</div>
);
const markup = ReactDOMServer.renderToStaticMarkup(reactElement);
domElement.innerHTML = markup;
ReactDOM.hydrate(reactElement, domElement);
expect(domElement.innerHTML).toEqual(markup);
});
it('should warn if innerHTML mismatches with dangerouslySetInnerHTML=undefined and children on the client', () => {
const domElement = document.createElement('div');
const markup = ReactDOMServer.renderToStaticMarkup(
<div dangerouslySetInnerHTML={{__html: '<p>server</p>'}} />,
);
domElement.innerHTML = markup;
expect(() => {
ReactDOM.hydrate(
<div dangerouslySetInnerHTML={undefined}>
<p>client</p>
</div>,
domElement,
);
expect(domElement.innerHTML).not.toEqual(markup);
}).toErrorDev(
'Warning: Text content did not match. Server: "server" Client: "client"',
);
});
it('should warn if innerHTML mismatches with dangerouslySetInnerHTML=undefined on the client', () => {
const domElement = document.createElement('div');
const markup = ReactDOMServer.renderToStaticMarkup(
<div dangerouslySetInnerHTML={{__html: '<p>server</p>'}} />,
);
domElement.innerHTML = markup;
expect(() => {
ReactDOM.hydrate(<div dangerouslySetInnerHTML={undefined} />, domElement);
expect(domElement.innerHTML).not.toEqual(markup);
}).toErrorDev(
'Warning: Did not expect server HTML to contain a <p> in <div>',
);
});
});
+5 -6
View File
@@ -1110,12 +1110,11 @@ export function diffHydratedProperties(
} else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
const serverHTML = domElement.innerHTML;
const nextHtml = nextProp ? nextProp[HTML] : undefined;
const expectedHTML = normalizeHTML(
domElement,
nextHtml != null ? nextHtml : '',
);
if (expectedHTML !== serverHTML) {
warnForPropDifference(propKey, serverHTML, expectedHTML);
if (nextHtml != null) {
const expectedHTML = normalizeHTML(domElement, nextHtml);
if (expectedHTML !== serverHTML) {
warnForPropDifference(propKey, serverHTML, expectedHTML);
}
}
} else if (propKey === STYLE) {
// $FlowFixMe - Should be inferred as not undefined.