web-dev-qa-db-fra.com

React - Comment passer des balises HTML dans les accessoires?

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?

71
ffxsam

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.

104
matagus

En fait, il y a plusieurs façons d'aller avec cela.

Vous voulez utiliser JSX dans vos accessoires

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 ()}.

Vous voulez transmettre uniquement du HTML en tant que chaîne

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.

La manière tableau

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:

  • Cela créera un avertissement (clés manquantes)
  • Ce n'est pas lisible
  • Ce n'est pas vraiment la manière JSX, c'est plus un hack qu'un design prévu.

Le chemin des enfants

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).

61
Atrakeur

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>
    );
   },
6
Shashi3456643
<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.

5
Catalin

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 ...

1 - Définir le prop comme jsx (ma préférence)

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.). 

2 - Définir dangereusement le innerHtml

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

5
Vijay Selvan Ram

À 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

4
RynoRn

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>)
   }
}
3
Adeel Imran

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

});
1
alli

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."]} />
0
Jaison

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."]} />
0
Osama Bari

L'analyseur de html-react-parser est une bonne solution. Il faut juste 

  • installez-le avec npm ou fil
  • importer un analyseur depuis 'html-react-parser'; 
  • appelez-le avec:

    <MyComponent text=Parser("This is <strong>not</strong> working.") />
    

    et ça marche bien.

0
Franck212

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

Exemple Plunkr

Réagir doc pour dangereusementSetInnerHTML

0
Rajkishor Sahu

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.

https://www.npmjs.com/package/react-html-parser

0
Daniel Lefebvre

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>
);
0
Nick Louloudakis