React - Comment passer des balises HTML dans les accessoires?

118

Je veux pouvoir transmettre du texte avec des balises HTML, comme ceci:

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

Mais à l'intérieur de MyComponentla méthode de rendu de 's, quand j'imprime this.props.text, il imprime littéralement tout:

This is <strong>not</strong> working.

Existe-t-il un moyen pour que React analyse le HTML et le vider correctement?

ffxsam
la source
Quelle est votre fonction de rendu réelle?
Lucio
3
Le modèle typique serait de faire de votre contenu des enfants de votre composant <MyComponent>This is <strong>not</strong> working</MyComponent>, au lieu de les passer comme accessoires. Pourriez-vous donner plus de contexte sur ce que vous essayez réellement d'accomplir?
Nick Tomlin
Presque la même question: Reactjs convertit en html .
totymedli

Réponses:

140

Vous pouvez utiliser des tableaux mixtes 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 HTML brut, mais soyez prudent car cela peut vous ouvrir à une attaque de script intersite (XSS) si vous ne nettoyez pas les valeurs de propriété.

matagus
la source
10
Cela fonctionne, sauf que je reçois maintenant un avertissement: Attention: chaque enfant d'un tableau ou d'un itérateur doit avoir un accessoire "clé" unique. Vérifiez la méthode de rendu de CTA. Il a été passé un enfant de Template1. Voir fb.me/react-warning-keys pour plus d'informations.
ffxsam
3
Vous pouvez faire disparaître cette erreur en parcourant le tableau et en ajoutant l'index comme clé dans MyComponent {text.map( textOrHTML, index) => <span key={index}>{textOrHTML}</span> )} Bien que ce soit tellement étrange que nous devions le faire en premier lieu entièrement.
HussienK
5
Vous pouvez également corriger l'avertissement en mettant key="[some unique value]"l' <strong>élément.
Chad Johnson
Bien, fonctionne bien, j'aimerais savoir comment pourrais-je utiliser une variable à l'intérieur forte au lieu de la chaîne 'not'
Jaison
2
Afin de supprimer l'avertissement de clé de tableau, il est également possible maintenant de passer un seul JSX comme celui-ci. <MyComponent text={<>This is <strong>not</strong> working.</>} />
Arif
111

En fait, il y a plusieurs façons d'y parvenir.

Vous souhaitez 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 retournera des composants JSX (tout comme la fonction de rendu standard), puis d'appeler simplement myProp = {this.renderMyProp ()}

Vous souhaitez transmettre uniquement du HTML sous forme de chaîne

Par défaut, JSX ne vous permet pas de rendre du 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>

Attention, cette solution «peut» s'ouvrir sur des attaques de falsification de scripts intersites. Méfiez-vous également que vous ne pouvez rendre que du HTML simple, aucune balise ou composant JSX ou d'autres choses sophistiquées.

La manière du tableau

Dans react, vous pouvez passer un tableau d'éléments JSX. Cela 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.

La manière des enfants

En l'ajoutant par souci d'exhaustivité, mais en réaction, 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 sous la forme this.props.children dans SomeComponent et pourront être rendus avec la syntaxe standard {}.

Cette solution est parfaite lorsque vous n'avez qu'un seul contenu HTML à transmettre à votre composant (imaginez un composant Popin qui ne prend que le contenu du Popin comme enfant).

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)

Atrakeur
la source
1
this.props.childrens - mais this.props.children. Sans 's' reactjs.org/docs/glossary.html#propschildren
Alexiuscrow
13

Vous pouvez utiliser dangereusementSetInnerHTML

Envoyez simplement le code HTML sous forme de chaîne normale

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

Et restituer dans le code JSX comme ceci:

<h2 className="header-title-right wow fadeInRight"
    dangerouslySetInnerHTML={{__html: props.text}} />

Faites juste attention si vous restituez des données saisies par l'utilisateur. Vous pouvez être victime d'une attaque XSS

Voici la documentation: https://facebook.github.io/react/tips/dangerously-set-inner-html.html

hecontreraso
la source
7
<MyComponent text={<span>This is <strong>not</strong> working.</span>} />

puis dans votre composant, vous pouvez faire la 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 ne choisir qu'un seul type d'accessoire.


la source
6

Pour moi, cela a fonctionné en passant une balise 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>
    );
   },
Shashi3456643
la source
6

Sur une application de réaction côté client, il existe plusieurs façons de rendre un accessoire sous forme de chaîne avec du HTML. L'un plus sûr que l'autre ...

1 - Définissez 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 quel que soit le fichier qui génère cet accessoire, il doit inclure React en tant que dépendance (au cas où vous générez le jsx de l'accessoire dans un fichier d'assistance, etc.).

2 - Définir dangereusement le innerHtml

const someProps = {
  greeting: '<React.Fragment>Hello<a href="https://stackoverflow.com/${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éconseillée. Imaginez un champ d'entrée dont la valeur d'entrée est rendue comme accessoire dans ce composant. Un utilisateur pourrait entrer une balise de script dans l'entrée et le composant qui restitue cette entrée exécuterait ce code potentiellement malveillant. En tant que telle, cette approche a le potentiel d'introduire des vulnérabilités de script intersite. Pour plus d'informations, reportez - vous à la documentation officielle de React

Vijay Selvan Ram
la source
4

Définissez le type d'accessoire de texte sur any et procédez comme suit:

<MyComponent text={
    <React.Fragment>
        <div> Hello, World!</div>
    </React.Fragment>
    } 
/>

Exemple

Amey Parundekar
la source
3

Vous pouvez le faire de 2 manières dont je suis conscient.

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, faites-le 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>)
   }
}
Adeel Imran
la source
1
J'ai ajouté une variable let vhtml = "<p>Test</p>"et l' ai utilisée sur l'accessoire comme ceci text={vhtml}et elle est toujours restituée en texte brut pour une raison quelconque.
Si8
2

La réponse @matagus me convient, Hope below snippet aide ceux qui souhaitent utiliser une variable à l'intérieur.

const myVar = 'not';
<MyComponent text={["This is ", <strong>{`${myVar}`}</strong>,  "working."]} />
Jaison
la source
1

Dans mon projet, j'ai dû transmettre un extrait de code HTML dynamique de la variable et le rendre à l'intérieur du composant. J'ai donc fait ce qui suit.

defaultSelection : {
    innerHtml: {__html: '<strong>some text</strong>'}
}

L' objet defaultSelection est passé au composant à partir du .jsfichier

<HtmlSnippet innerHtml={defaultSelection.innerHtml} />

Composant HtmlSnippet

var HtmlSnippet = React.createClass({
  render: function() {
    return (
      <span dangerouslySetInnerHTML={this.props.innerHtml}></span>
    );
  }
});

Exemple de Plunkr

réagir doc pour dangerouslySetInnerHTML

Rajkishor Sahu
la source
1

Vous pouvez également utiliser une fonction sur le composant pour transmettre jsx à through props. 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>
     );
  },

});
Allison
la source
1

Oui, vous pouvez le faire en utilisant un tableau de mixage avec des chaînes et des éléments JSX. référence

<MyComponent text={["This is ", <strong>not</strong>,  "working."]} />
Osama Bari
la source
1

Analyseur de html-react-parser est une bonne solution. Tu dois juste

  • installez-le avec npm ou fil
  • import Parser depuis 'html-react-parser';
  • appelez-le avec:

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

    et ça marche bien.

Franck212
la source
1

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 manière très élégante est d'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>
);
Nick L.
la source
1

Cette question a déjà beaucoup de réponses, mais j'avais fait quelque chose de mal à ce sujet et je pense que cela vaut la peine d'être partagé:

J'avais quelque chose comme ça:

export default function Features() {
  return (
    <Section message={<p>This is <strong>working</strong>.</p>} />
  }
}

mais le massage était plus long que cela, alors j'ai essayé d'utiliser quelque chose comme ceci:

const message = () => <p>This longer message is <strong>not</strong> working.</p>;

export default function Features() {
  return (
    <Section message={message} />
  }
}

Il m'a fallu un certain temps pour réaliser que je manquais le () dans l'appel de fonction.

Ca ne fonctionne pas

<Section message={message} />

Travail

<Section message={message()} />

peut-être que cela vous aide, comme cela m'a aidé!

Abraham Hernandez
la source
1

Vous pouvez utiliser avec succès les fragments React pour cette tâche. Selon l'utilisation React version que vous, vous pouvez utiliser la syntaxe courte: <>ou l'étiquette complète: <React.Fragment>. Fonctionne particulièrement bien si vous ne souhaitez pas envelopper la chaîne entière dans des balises HTML.

<MyComponent text={<>Hello World. <u>Don't be so ruthless</u>.</>} />
Cyclone
la source
0

Nous pouvons faire la même chose de cette manière.

const Child = () => {
  return (
     write your whole HTML here.
  )
}

maintenant vous voulez envoyer ce HTML dans un autre composant dont le nom est le composant Parent.

Appel: -

<Parent child={<child/>} >
</Parent> 

Utilisation de l'enfant: -

 const Parent = (props) => {
   const { child } = props; 
   return (
       {child}
    )
}

ce travail parfait pour moi.

pushparmar
la source
-9

Ont ajouté le code HTML dans componentDidMount à l'aide de jQuery append. Cela devrait résoudre le problème.

 var MyComponent = React.createClass({
    render: function() {

        return (
           <div>

           </div>
        );
    },
    componentDidMount() {
        $(ReactDOM.findDOMNode(this)).append(this.props.text);
    }
});
Kaushik
la source
5
Ceci est voté à la baisse parce que vous ne devriez pas utiliser la manipulation directe du DOM de jquery combinée à la manipulation indirecte du DOM de react, car cela peut conduire à un problème de navigateur.
Allison