React: dangerouslySetInnerHTML is left empty on client render on top of bad server markup when rendering HTML

Created on 20 Mar 2019  ·  9Comments  ·  Source: facebook/react

This 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:

  1. Server-side stuff comes in from server and contains the things we need
  2. Hydration mismatch happens
  3. 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:

```js

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);
  },
);

```bash
      ✓ 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.

Bug Needs Investigation

Most helpful comment

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.

All 9 comments

Do you want to try to fix it?

@gaearon sure! :) Already dove into it a bit

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution.

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please create a new issue with up-to-date information. Thank you!

Still relevant?

I think i may have ran into this today. Haven't done that much research, and i'm pretty new in the react world. Is there any kind of work around?

Sorry, I forgot totally about this...

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 think I may be hitting this issue with a Gatsby site. I will see if I can create a streamlined version of the site that can reliably recreate the issue and I will share that as a debugging tool.

React v16.13.1
React-DOM v16.13.1

Edit: What @olaj mentioned seems to fix the issue in my case

Was this page helpful?
0 / 5 - 0 ratings