简体   繁体   中英

React dangerouslySetInnerHTML not working when using variable

I'm creating an SPA using React that searches data and displays results. Each result follows the following model

{
  "title": "A Title",
  "body": " <li>escaped html <strong>that sould be rendered</strong>.</li>
    </ul>"
}

The body property is always an escaped html that should be rendered in a component. This component looks like this:

Code

function SearchResult({ title, body, favourite }) {
  return (
    <article className="SearchResult">
    <section>
      <i className={`icon-star${favourite ? ' marked' : ''}`} />
      {title}
    </section>
    <section
      dangerouslySetInnerHTML={{ __html: body }}
      className="SearchResult-body"
    />
  </article>
  );
}

but the body of each result is not being rendered correctly, instead, it shows the html as a text 在此处输入图片说明 在此处输入图片说明

The issue is that it only happens when I create the component passing a variable to the body property

results.map((result, index) => (
      <SearchResult key={index} title={result.title} body={result.body} />
    ))

But if I do this, it works fine

<SearchResult
    title="A title"
    body=" &lt;li&gt;escaped html&amp;nbsp;&lt;strong&gt;that sould be rendered&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;"
  />

Why is this different? Is there any preprocessing that I should add to the value before passing it in the property that is added by default when I use the fixed value?

Demo

A demo of this issue can be seen here

It seems like this issue only occurs when you give it an escaped html.

A solution implemented by @sergiotapia involves creating a helper function to unescape the html string to make it work.

htmlDecode(content) {
  let e = document.createElement('div');
  e.innerHTML = content;
  return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
<section
  dangerouslySetInnerHTML={{ __html: htmlDecode(body) }}
  className="SearchResult-body"
/>

However as @brigand mentioned and I'll quote " Unescaping it could allow for XSS attacks and incorrect rendering. " so this might not be the perfect solution for this.

See working example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM