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.
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é.
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
-
facile -utilisez Unicode, enregistrez le fichier comme UTF-8 et mettez le
charset
à UTF-8.<div>{'First · Second'}</div>
-
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>
-
Ou une matrice mixte, avec des cordes et JSX éléments.
<div>{['First ', <span>·</span>, ' Second']}</div>
-
dernier recours - insérer brut HTML utilisant
dangerouslySetInnerHTML
.<div dangerouslySetInnerHTML={{__html: 'First · Second'}} />
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>
)
}
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>
)
}
}
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
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
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 · Second'}</RawHTML>
<RawHTML tag="h2">{'First · Second'}</RawHTML>
<RawHTML tag="h2" className="test">{'First · 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 · Second</h1></RawHTML>