2 votes

React dangerouslySetInnerHTML ne fonctionne pas quand on utilise une variable

Je suis en train de créer un SPA utilisant React qui recherche des données et affiche les résultats. Chaque résultat suit le modèle suivant

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

El body est toujours un html échappé qui doit être rendu dans un composant. Ce composant ressemble à ceci :

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

mais le corps de chaque résultat n'est pas rendu correctement, au lieu de cela, il affiche le html comme un texte. enter image description here enter image description here

Le problème est que cela ne se produit que lorsque je crée le composant en passant une variable à la fonction body propriété

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

Mais si je fais ceci, cela fonctionne bien

<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;"
  />

Pourquoi est-ce différent ? Y a-t-il un prétraitement que je devrais ajouter à la valeur avant de la passer dans la propriété, qui est ajouté par défaut lorsque j'utilise la valeur fixe ?

Démo

Une démonstration de ce problème peut être vue aquí

3voto

Ana Liza Pandac Points 566

Il semble que numéro ne se produit que lorsque vous lui donnez un html échappé.

Une solution mise en œuvre par @sergiotapia implique la création d'une fonction d'aide pour désencoder la chaîne html afin de la faire fonctionner.

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"
/>

Cependant, comme @brigand a mentionné et je cite " Le fait de le décoder pourrait permettre des attaques XSS et un rendu incorrect. "Il se peut donc que cette solution ne soit pas parfaite.

Ver exemple de travail

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X