Rendre HTML brut avec reactjs

est-ce la seule façon de rendre HTML brut avec reactjs?

// http://facebook.github.io/react/docs/tutorial.html
// tutorial7.js
var converter = new Showdown.converter();
var Comment = React.createClass({
  render: function() {
    var rawMarkup = converter.makeHtml(this.props.children.toString());
    return (
      <div className="comment">
        <h2 className="commentAuthor">
          {this.props.author}
        </h2>
        <span dangerouslySetInnerHTML={{__html: rawMarkup}} />
      </div>
    );
  }
});

je sais qu'il y a des façons cool de marquer des trucs avec JSX, mais je suis surtout intéressé à être capable de rendre HTML brut (avec toutes les classes, styles inline, etc..). Quelque chose de compliqué comme ceci:

<!-- http://getbootstrap.com/components/#dropdowns-example -->
<div class="dropdown">
  <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-expanded="true">
    Dropdown
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Action</a></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another action</a></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Something else here</a></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Separated link</a></li>
  </ul>
</div>

je ne voudrais pas avoir à réécrire tout cela dans JSX.

peut-être que j'y pense mal. Merci de me corriger.

80
demandé sur Al.G. 2015-01-14 04:01:27

7 réponses

vous pouvez utiliser le html-to-react module npm à https://www.npmjs.com/package/html-to-react .

Note: je suis l'auteur du module et je l'ai publié il y a quelques heures. N'hésitez pas à signaler tout bogue ou problème d'utilisabilité.

21
répondu Mike Nikles 2015-06-21 00:02:30

il existe maintenant des méthodes plus sûres pour rendre HTML. J'ai couvert cela dans une réponse précédente ici . Vous avez 4 options, les dernières utilisations dangerouslySetInnerHTML .

méthodes pour rendre HTML

  1. facile -utilisez Unicode, enregistrez le fichier comme UTF-8 et mettez le charset à UTF-8.

    <div>{'First · Second'}</div>

  2. Safer - utilisez le numéro Unicode pour l'entité à l'intérieur d'une chaîne Javascript.

    <div>{'First \u00b7 Second'}</div>

    ou

    <div>{'First ' + String.fromCharCode(183) + ' Second'}</div>

  3. Ou une matrice mixte, avec des cordes et JSX éléments.

    <div>{['First ', <span>&middot;</span>, ' Second']}</div>

  4. dernier recours - insérer brut HTML utilisant dangerouslySetInnerHTML .

    <div dangerouslySetInnerHTML={{__html: 'First &middot; Second'}} />

112
répondu Brett DeWoody 2017-05-23 12:03:04

j'ai utilisé ceci dans des situations rapides et sales:

// react render method:

render() {
    return (
      <div>
        { this.props.textOrHtml.indexOf('</') !== -1
            ? (
                <div dangerouslySetInnerHTML={{__html: this.props.textOrHtml.replace(/(<? *script)/gi, 'illegalscript')}} >
                </div>
              )
            : this.props.textOrHtml
          }

      </div>
      )
  }
12
répondu Cory Robinson 2017-10-15 16:39:47
export class ModalBody extends Component{
    rawMarkup(){
        var rawMarkup = this.props.content
        return { __html: rawMarkup };
    }
    render(){
        return(
                <div className="modal-body">
                     <span dangerouslySetInnerHTML={this.rawMarkup()} />

                </div>
            )
    }
}
8
répondu Jozcar 2017-03-18 02:45:55

j'ai essayé ce composant pur:

const RawHTML = ({children, className = ""}) => 
<div className={className}
  dangerouslySetInnerHTML={{ __html: children.replace(/\n/g, '<br />')}} />

Caractéristiques

  • Prend className prop (plus facile pour le style il)
  • remplace \n par <br /> (vous voulez souvent faire cela)
  • contenu enfants lors de l'utilisation du composant comme:
  • <RawHTML>{myHTML}</RawHTML>

j'ai placé le composant dans un Gist à Github: RawHTML: ReactJS pur component to render HTML

8
répondu Netsi1964 2017-08-22 06:31:43

dangerouslySetInnerHTML ne doit pas être utilisé sauf en cas d'absolue nécessité. Selon les docs, "Ceci est principalement pour coopérer avec les bibliothèques de manipulation de chaînes DOM" . Lorsque vous l'utilisez, vous renoncez au bénéfice de la gestion DOM de React.

dans votre cas, il est assez simple de passer à la syntaxe valide JSX, il suffit de changer les attributs class en className . Ou, comme mentionné dans les commentaires ci-dessus, vous pouvez utiliser le bouton ReactBootstrap de la bibliothèque qui encapsule Bootstrap éléments Réagir composants

3
répondu Breno Ferreira 2015-01-14 12:58:29

Voici une version un peu moins opiniâtre de la fonction RawHTML affichée avant. Il vous permet:

  • configurer la balise
  • remplacer éventuellement les nouvelles lignes par <br /> 's
  • passer accessoires supplémentaires que RawHTML passera à l'élément créé
  • fournir une chaîne vide ( RawHTML></RawHTML> )

voici le composant:

const RawHTML = ({ children, tag = 'div', nl2br = true, ...rest }) =>
    React.createElement(tag, {
        dangerouslySetInnerHTML: {
            __html: nl2br
                ? children && children.replace(/\n/g, '<br />')
                : children,
        },
        ...rest,
    });
RawHTML.propTypes = {
    children: PropTypes.string,
    nl2br: PropTypes.bool,
    tag: PropTypes.string,
};

Utilisation:

<RawHTML>{'First &middot; Second'}</RawHTML>
<RawHTML tag="h2">{'First &middot; Second'}</RawHTML>
<RawHTML tag="h2" className="test">{'First &middot; Second'}</RawHTML>
<RawHTML>{'first line\nsecond line'}</RawHTML>
<RawHTML nl2br={false}>{'first line\nsecond line'}</RawHTML>
<RawHTML></RawHTML>

sortie:

<div>First · Second</div>
<h2>First · Second</h2>
<h2 class="test">First · Second</h2>
<div>first line<br>second line</div>
<div>first line
second line</div>
<div></div>

Il va se casser sur:

<RawHTML><h1>First &middot; Second</h1></RawHTML>
0
répondu Christiaan Westerbeek 2018-07-11 12:32:52