dangerouslySetInnerHTML is left empty on client render on top of bad server markup when rendering HTML
See original GitHub issueThis seems to be an edge case of https://github.com/facebook/react/issues/11789 fixed in https://github.com/facebook/react/pull/13353/files.
I ran into this when trying to hydrate content rendered with https://github.com/prismicio/prismic-dom asHtml
method.
Do you want to request a feature or report a bug?
Bug? I think.
What is the current behavior?
Current behavior:
- Server-side stuff comes in from server and contains the things we need
- Hydration mismatch happens
- dangerouslySetInnerHTML is called with correct value but an empty string gets rendered instead
I tried to replicate the issue on https://codesandbox.io/s/2xojk10jln but failed.
The following testcase for packages/react-dom/src/__tests__/ReactDOMServerIntegrationElements-test.js
produces the same result (I tried it first with the same PrismicDOM.RichText.asHtml(obj) call I have in the app) but I am not sure if it’s correct:
# test case
itRenders(
'a div with dangerouslySetInnerHTML set to html inserted',
async render => {
const obj = '<li>bar</li>';
const e = await render(
<div dangerouslySetInnerHTML={{__html: obj }} />,
);
expect(e.childNodes.length).toBe(1);
expect(e.firstChild.tagName).toBe('LI');
expect(e.firstChild.childNodes.length).toBe(1);
},
);
✓ renders a div with dangerouslySetInnerHTML set to html return value of function called with server string render (190ms)
✓ renders a div with dangerouslySetInnerHTML set to html return value of function called with server stream render (52ms)
✓ renders a div with dangerouslySetInnerHTML set to html return value of function called with clean client render (37ms)
✓ renders a div with dangerouslySetInnerHTML set to html return value of function called with client render on top of good server markup (74ms)
✕ renders a div with dangerouslySetInnerHTML set to html return value of function called with client render on top of bad server markup (34ms)
● ReactDOMServerIntegration › ... › renders a div with dangerouslySetInnerHTML set to html return value of function called with client render on top of bad server markup
expect(received).toBe(expected) // Object.is equality
Expected: "bar"
Received: ""
What is the expected behavior?
The client render would have rendered <li>bar</li>
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
commit c05b4b8 (latest master) and >16.8.
Sorry for a bit vague bug report.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:13 (6 by maintainers)
Hmm … but im not sure it was this for me. Or it seemed that i tried to render a
<p>
inside a<p>
and when i removed the parent<p>
it seems to work. Not sure if that is expected or not.I hit this issue today and here’s a quick repro.
I’m not completely sure about what the desired behavior should be here, as nesting paragraph elements isn’t compliant with HTML5’s spec.
Using straight JSX produces the “desired” output, even though incorrect
On the other hand, using
dangerouslySetInnerHTML
automatically closes nested paragraph elements