Je veux pouvoir passer du texte avec des balises HTML, comme ceci:
<MyComponent text="This is <strong>not</strong> working." />
Mais à l’intérieur de la méthode de rendu de MyComponent
, lorsque j’imprime this.props.text
, il affiche littéralement tout:
This is <strong>not</strong> working.
Existe-t-il un moyen de faire en sorte que React analyse le HTML et le vide correctement?
Vous pouvez utiliser des tableaux mélangés avec des chaînes et des éléments JSX (voir la documentation ici ):
<MyComponent text={["This is ", <strong>not</strong>, "working."]} />
Il y a un violon ici qui montre que cela fonctionne: http://jsfiddle.net/7s7dee6L/
De plus, en dernier recours, vous avez toujours la possibilité d'insérer du code HTML brut mais soyez prudent, cela peut vous ouvrir le droit à une attaque par script intersite (XSS) si les valeurs de propriété ne sont pas nettoyées.
En fait, il y a plusieurs façons d'aller avec cela.
Vous pouvez simplement utiliser {} pour que JSX analyse le paramètre. La seule limitation est la même que pour chaque élément JSX: il ne doit renvoyer qu'un seul élément racine.
myProp={<div><SomeComponent>Some String</div>}
La meilleure façon de procéder est de créer une fonction renderMyProp qui renverra les composants JSX (exactement comme la fonction de rendu standard), puis d'appeler simplement myProp = {this.renderMyProp ()}.
Par défaut, JSX ne vous permet pas de générer du code HTML brut à partir de valeurs de chaîne. Cependant, il existe un moyen de le faire:
myProp="<div>This is some html</div>"
Ensuite, dans votre composant, vous pouvez l'utiliser comme ça:
<div dangerouslySetInnerHTML=myProp={{ __html: this.renderMyProp() }}></div>
Notez que cette solution peut «s'ouvrir» lors d'attaques de contrefaçons de script intersite. Sachez également que vous ne pouvez générer que du HTML simple, pas de balise ni de composant JSX, ni d’autres éléments fantaisistes.
En réagissant, vous pouvez passer un tableau d'éléments JSX ..__, ce qui signifie:
myProp={["This is html", <span>Some other</span>, "and again some other"]}
Je ne recommanderais pas cette méthode car:
En l'ajoutant par souci d'exhaustivité, mais en réagissant, vous pouvez également obtenir tous les enfants qui sont "à l'intérieur" de votre composant.
Donc si je prends le code suivant:
<SomeComponent>
<div>Some content</div>
<div>Some content</div>
</SomeComponent>
Ensuite, les deux divs seront disponibles en tant que this.props.children dans SomeComponent et pourront être restitués avec la syntaxe standard {}.
Cette solution est parfaite lorsque vous n'avez qu'un seul contenu HTML à transmettre à votre composant (imaginez un composant Popin prenant uniquement le contenu du Popin sous la forme d'enfants).
Cependant, si vous avez plusieurs contenus, vous ne pouvez pas utiliser d'enfants (ou vous devez au moins le combiner avec une autre solution ici).
Pour moi, cela a fonctionné en passant tag HTML dans les accessoires enfants
<MyComponent>This is <strong>not</strong> working.</MyComponent>
var MyComponent = React.createClass({
render: function() {
return (
<div>this.props.children</div>
);
},
<MyComponent text={<span>This is <strong>not</strong> working.</span>} />
et ensuite dans votre composant, vous pouvez faire une vérification des accessoires comme ceci:
import React from 'react';
export default class MyComponent extends React.Component {
static get propTypes() {
return {
text: React.PropTypes.object, // if you always want react components
text: React.PropTypes.any, // if you want both text or react components
}
}
}
Assurez-vous de choisir un seul type d'accessoire.
Sur une application de réaction côté client, il existe deux manières de rendre un accessoire sous forme de chaîne avec du HTML. L'un plus sûr que l'autre ...
const someProps = {
greeting: {<div>Hello<a href="/${name_profile}">${name_profile}</a></div>}
}
const GreetingComopnent = props => (
<p>{props.someProps.greeting}</p>
)
• La seule exigence ici est que le fichier générant cet accessoire doit inclure React en tant que dépendance (si vous générez le fichier jsx de l'accessoire dans un fichier d'assistance, etc.).
const someProps = {
greeting: '<React.Fragment>Hello<a href="/${name_profile}">${name_profile}</a></React.Fragment>'
}
const GreetingComponent = props => {
const innerHtml = { __html: props.someProps.greeting }
return <p dangerouslySetInnerHtml={innerHtml}></p>
}
• Cette seconde approche est découragée. Imaginez un champ d’entrée dont la valeur d’entrée est restituée comme un accessoire dans ce composant. Un utilisateur peut entrer une balise de script dans l'entrée et le composant qui rend cette entrée exécute ce code potentiellement malveillant. En tant que telle, cette approche est susceptible d’introduire des vulnérabilités de script intersite . Pour plus d’informations, reportez-vous aux documents officiels de React
À partir de la version 16.02 de React, vous pouvez utiliser un fragment.
<MyComponent text={<Fragment>This is an <strong>HTML</strong> string.</Fragment>} />
Plus d'infos: https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html
Vous pouvez le faire de deux manières que je connaisse.
1- <MyComponent text={<p>This is <strong>not</strong> working.</p>} />
Et puis fais ça
class MyComponent extends React.Component {
render () {
return (<div>{this.props.text}</div>)
}
}
Ou deuxième approche le faire comme ça
2- <MyComponent><p>This is <strong>not</strong> working.</p><MyComponent/>
Et puis fais ça
class MyComponent extends React.Component {
render () {
return (<div>{this.props.children}</div>)
}
}
Vous pouvez également utiliser une fonction sur le composant pour transmettre jsx aux accessoires. comme:
var MyComponent = React.createClass({
render: function() {
return (
<OtherComponent
body={this.body}
/>
);
},
body() {
return(
<p>This is <strong>now</strong> working.<p>
);
}
});
var OtherComponent = React.createClass({
propTypes: {
body: React.PropTypes.func
},
render: function() {
return (
<section>
{this.props.body()}
</section>
);
},
});
La réponse de @matagus est correcte pour moi, J'espère que l'extrait de code est aidé pour ceux qui souhaitent utiliser une variable interne.
const myVar = 'not';
<MyComponent text={["This is ", <strong>{`${myVar}`}</strong>, "working."]} />
Oui, vous pouvez le faire en utilisant Mix tableau avec des chaînes et des éléments JSX. référence
<MyComponent text={["This is ", <strong>not</strong>, "working."]} />
L'analyseur de html-react-parser est une bonne solution. Il faut juste
appelez-le avec:
<MyComponent text=Parser("This is <strong>not</strong> working.") />
et ça marche bien.
Dans mon projet, je devais transmettre un extrait dynamique de variable HTML et le restituer dans un composant. Alors j'ai fait ce qui suit.
defaultSelection : {
innerHtml: {__html: '<strong>some text</strong>'}
}
L'objet defaultSelection est transmis au composant à partir du fichier .js
<HtmlSnippet innerHtml={defaultSelection.innerHtml} />
Composant HtmlSnippet
var HtmlSnippet = React.createClass({
render: function() {
return (
<span dangerouslySetInnerHTML={this.props.innerHtml}></span>
);
}
});
Y a-t-il une raison pour laquelle personne n'a suggéré de réagir-html-parser? Cela semble être un bon moyen de travailler avec du HTML importé sans avoir à le faire dangereusement.
Ajout à la réponse: Si vous avez l’intention d’analyser et que vous êtes déjà dans JSX mais que vous avez un objet avec des propriétés imbriquées, une méthode très élégante consiste à utiliser des parenthèses afin de forcer l’analyse JSX:
const TestPage = () => (
<Fragment>
<MyComponent property={
{
html: (
<p>This is a <a href='#'>test</a> text!</p>
)
}}>
</MyComponent>
</Fragment>
);