Insérer du HTML avec des instructions variables React (JSX)


204

Je construis quelque chose avec React où j'ai besoin d'insérer du HTML avec des variables React dans JSX. Existe-t-il un moyen d'avoir une variable comme ceci:

var thisIsMyCopy = '<p>copy copy copy <strong>strong copy</strong></p>';

et de l'insérer dans réagir comme ça, et ça marche?

render: function() {
    return (
        <div className="content">{thisIsMyCopy}</div>
    );
}

et le faire insérer le HTML comme prévu? Je n'ai rien vu ni entendu parler d'une fonction de réaction qui pourrait faire cela en ligne, ou d'une méthode d'analyse syntaxique qui permettrait à cela de fonctionner.

Réponses:


296

Vous pouvez utiliser dangereusement SetInnerHTML , par exemple

render: function() {
    return (
        <div className="content" dangerouslySetInnerHTML={{__html: thisIsMyCopy}}></div>
    );
}

2
Comment cela fonctionne-t-il si vous devez ajouter quelque chose <head>?
Danielle Madeley

Les méthodes DOM normales dans componentDidMount devraient fonctionner, je ne l'ai pas fait auparavant cependant.
Douglas

@DanielleMadeley Essayez-vous d'insérer des commentaires IE conditionnels dans <head>? Si c'est le cas, j'ai réussi à utiliser l'astuce décrite ici: nemisj.com/conditional-ie-comments-in-react-js
Cam Jackson

3
Assurez-vous de passer une méthode à dangerouslySetInnerHTML et non un hachage. Selon les documents, il est dangereux de simplement passer un hachage. Référence: facebook.github.io/react/tips/dangerously-set-inner-html.html
criterz

1
Existe-t-il un moyen sans insérer le div?
mec

102

Notez que cela dangerouslySetInnerHTMLpeut être dangereux si vous ne savez pas ce qu'il y a dans la chaîne HTML que vous injectez. En effet, du code côté client malveillant peut être injecté via des balises de script.

C'est probablement une bonne idée de nettoyer la chaîne HTML via un utilitaire tel que DOMPurify si vous n'êtes pas sûr à 100% que le HTML que vous restituez est sûr XSS (cross-site scripting).

Exemple:

import DOMPurify from 'dompurify'

const thisIsMyCopy = '<p>copy copy copy <strong>strong copy</strong></p>';


render: function() {
    return (
        <div className="content" dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(thisIsMyCopy)}}></div>
    );
}

@vsync non ça ne devrait pas :)
Artem Bernatskyi

1
est-il possible de rendre non seulement des balises html, mais aussi des balises de bibliothèque comme la balise ui Alert matérielle je veux que le code soit comme çaimport DOMPurify from 'dompurify' const thisIsMyCopy = '<Alert severity="warning">copy copy copy <strong>strong copy</strong></Alert >'; render: function() { return ( <div className="content" dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(thisIsMyCopy)}}></div> ); }
sasha romanov

@sasharomanov, Avez-vous trouvé une solution pour ce scénario?
Nimish goel

51

dangerouslySetInnerHTML présente de nombreux inconvénients car il est défini à l'intérieur de la balise.

Je vous suggère d'utiliser un wrapper React comme j'en ai trouvé un ici sur npm à cet effet. html-react-parser fait le même travail.

import Parser from 'html-react-parser';
var thisIsMyCopy = '<p>copy copy copy <strong>strong copy</strong></p>';


render: function() {
    return (
        <div className="content">{Parser(thisIsMyCopy)}</div>
    );
}

Très simple :)


3
"dangerouslySetInnerHTML présente de nombreux inconvénients car il se place à l'intérieur de la balise." Pouvez-vous expliquer plus à ce sujet. Essayer de réfléchir à la différence fondamentale qui existe entre html-react-parser et aseptisé innerHtml
dchhetri

Il semble que html-react-parser ne nettoie pas l'entrée - voir la FAQ
Little Brain

28

En utilisant, ''vous faites de la chaîne. Utilisez sans virgules inversées, cela fonctionnera bien.


14
Au début, j'ai ri, puis je lui ai donné une chance qui m'a époustouflé
M au

1
De loin la réponse la plus simple, surtout si le HTML est écrit par vous et dynamique en fonction des entrées de l'utilisateur. Vous pouvez littéralement définir var myHtml = <p> Du texte </p>; et ça marche
pat8719

1
C'est la meilleure réponse. Merci mon pote!
Andy Mercer

3

Pour éviter les erreurs de linter, je l'utilise comme ceci:

  render() {
    const props = {
      dangerouslySetInnerHTML: { __html: '<br/>' },
    };
    return (
        <div {...props}></div>
    );
  }

3
import { Fragment } from 'react' // react version > 16.0

var thisIsMyCopy = (
  <Fragment>
    <p>copy copy copy&nbsp;
    <strong>strong copy</strong>
    </p>
  </Fragment>
)

En utilisant '', la valeur est définie sur une chaîne et React n'a aucun moyen de savoir qu'il s'agit d'un élément HTML. Vous pouvez faire ce qui suit pour faire savoir à React qu'il s'agit d'un élément HTML -

  1. Retirez le ''et cela fonctionnerait
  2. Utilisez <Fragment>pour renvoyer un élément HTML.

2
Cela ne répond pas à la question. Le contenu de thisIsMyCopylui-même est JSX, pas une chaîne de HTML. Vous collez donc JSX dans JSX.
Antares42

Vous pouvez également trouver des fragments dans le pré-acte, mais uniquement dans la version X et les versions ultérieures.
Nasia Makrygianni

-3

Si quelqu'un d'autre atterrit encore ici. Avec ES6, vous pouvez créer votre variable html comme ceci:

render(){
    var thisIsMyCopy = (
        <p>copy copy copy <strong>strong copy</strong></p>
    );
    return(
        <div>
            {thisIsMyCopy}
        </div>
    )
}

2
et si vous voulez des variables à l'intérieur de votre chaîne, vous devrez envelopper chacune {}et la chaîne entière dans un balisage comme ça(<span>{telephoneNumber} <br /> {email}</span>)
DanV

2
C'est différent de ce qui est demandé dans la question. Dans la question <p>copy copy copy <strong>strong copy</strong></p>est une chaîne. Vous l'avez en tant que JSX.
YPCrumble

4
Ce n'est pas ES6, mais JSX
gztomas

-3

Vous pouvez également inclure ce code HTML dans ReactDOM comme ceci:

var thisIsMyCopy = (<p>copy copy copy <strong>strong copy</strong></p>);

ReactDOM.render(<div className="content">{thisIsMyCopy}</div>, document.getElementById('app'));

Voici deux liens link et link2 de la documentation React qui pourraient être utiles.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.