React - Come passare i tag HTML negli oggetti di scena?


118

Voglio essere in grado di passare il testo con tag HTML, in questo modo:

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

Ma all'interno del MyComponentmetodo di rendering di, quando stampo this.props.text, stampa letteralmente tutto:

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

C'è un modo per fare in modo che React analizzi l'HTML e lo scarichi correttamente?


Qual è la tua attuale funzione di rendering?
Lucio

3
Lo schema tipico sarebbe quello di rendere i tuoi contenuti figli del tuo componente <MyComponent>This is <strong>not</strong> working</MyComponent>, invece di passarli come oggetti di scena. Potresti fornire più contesto su ciò che stai effettivamente cercando di realizzare?
Nick Tomlin

Quasi la stessa domanda: Reactjs converte in html .
totymedli

Risposte:


140

Puoi usare array misti con stringhe ed elementi JSX (vedi la documentazione qui ):

<MyComponent text={["This is ", <strong>not</strong>,  "working."]} />

C'è un violino qui che mostra che funziona: http://jsfiddle.net/7s7dee6L/

Inoltre, come ultima risorsa, hai sempre la possibilità di inserire HTML grezzo ma fai attenzione perché questo può aprirti a un attacco di cross-site scripting (XSS) se non stai disinfettando i valori delle proprietà.


10
Funziona, eccetto che ora ricevo un avviso: Avviso: ogni figlio in un array o in un iteratore dovrebbe avere un prop "chiave" univoco. Controlla il metodo di rendering di CTA. È stato passato un bambino da Template1. Vedere fb.me/react-warning-keys per ulteriori informazioni.
ffxsam

3
Puoi fare in modo che questo errore scompaia passando attraverso l'array e aggiungendo l'indice come chiave in MyComponent {text.map( textOrHTML, index) => <span key={index}>{textOrHTML}</span> )} Anche se è così strano che dobbiamo farlo in primo luogo completamente.
HussienK

5
Puoi anche correggere l'avviso inserendo key="[some unique value]"l' <strong>elemento.
Chad Johnson

Bello, funziona bene, vorrei sapere come posso usare una variabile all'interno di strong invece della stringa "not"
Jaison

2
Per rimuovere l'avviso di chiave dell'array, ora è anche possibile passare un singolo JSX come questo. <MyComponent text={<>This is <strong>not</strong> working.</>} />
Arif

111

In realtà, ci sono molti modi per farlo.

Vuoi usare JSX all'interno dei tuoi oggetti di scena

Puoi semplicemente usare {} per fare in modo che JSX analizzi il parametro. L'unica limitazione è la stessa di ogni elemento JSX: deve restituire un solo elemento radice.

myProp={<div><SomeComponent>Some String</div>}

Il modo migliore per farlo è creare una funzione renderMyProp che restituirà componenti JSX (proprio come la funzione di rendering standard) e quindi chiamare semplicemente myProp = {this.renderMyProp ()}

Vuoi passare solo HTML come stringa

Per impostazione predefinita, JSX non consente di eseguire il rendering di HTML grezzo da valori di stringa. Tuttavia, c'è un modo per farlo:

myProp="<div>This is some html</div>"

Quindi nel tuo componente puoi usarlo in questo modo:

<div dangerouslySetInnerHTML=myProp={{ __html: this.renderMyProp() }}></div>

Attenzione che questa soluzione "può" aprirsi su attacchi falsi di scripting cross-site. Inoltre, fai attenzione che puoi solo rendere HTML semplice, nessun tag o componente JSX o altre cose fantasiose.

Il modo in cui l'array

In React, puoi passare un array di elementi JSX. Questo significa:

myProp={["This is html", <span>Some other</span>, "and again some other"]}

Non consiglierei questo metodo perché:

  • Creerà un avviso (chiavi mancanti)
  • Non è leggibile
  • Non è proprio il modo JSX, è più un hack che un design previsto.

Il modo dei bambini

Aggiungendolo per completezza ma in Reagire, puoi anche ottenere tutti i bambini che sono "dentro" il tuo componente.

Quindi se prendo il seguente codice:

<SomeComponent>
    <div>Some content</div>
    <div>Some content</div>
</SomeComponent>

Quindi i due div saranno disponibili come this.props.children in SomeComponent e possono essere visualizzati con la sintassi {} standard.

Questa soluzione è perfetta quando hai un solo contenuto HTML da passare al tuo componente (immagina un componente Popin che accetta solo il contenuto del Popin come figli).

Tuttavia, se hai più contenuti, non puoi usare i bambini (o devi almeno combinarli con un'altra soluzione qui)


1
this.props.childrens - ma this.props.children. Senza "s" reactjs.org/docs/glossary.html#propschildren
Alexiuscrow

13

Puoi usare pericolosamenteSetInnerHTML

Basta inviare l'html come una normale stringa

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

Ed esegui il rendering nel codice JSX in questo modo:

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

Fai solo attenzione se stai eseguendo il rendering dei dati inseriti dall'utente. Puoi essere vittima di un attacco XSS

Ecco la documentazione: https://facebook.github.io/react/tips/dangerously-set-inner-html.html


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

e poi nel tuo componente puoi fare il controllo prop in questo modo:

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

Assicurati di scegliere un solo tipo di oggetto.



6

Per me ha funzionato passando tag html in props children

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


var MyComponent = React.createClass({

   render: function() {
    return (
      <div>this.props.children</div>
    );
   },

6

Su un'applicazione React lato client, ci sono un paio di modi per rendere un prop come una stringa con un po 'di HTML. Uno più sicuro dell'altro ...

1 - Definisci l'elica come jsx (la mia preferenza)

const someProps = {
  greeting: {<div>Hello<a href="/${name_profile}">${name_profile}</a></div>}
}


const GreetingComopnent = props => (
  <p>{props.someProps.greeting}</p>
)

• L'unico requisito qui è che qualunque file stia generando questo prop deve includere React come dipendenza (nel caso tu stia generando il jsx del prop in un file di supporto, ecc.).

2 - Imposta pericolosamente il codice 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>
}

• Questo secondo approccio è sconsigliato. Immagina un campo di input il cui valore di input viene visualizzato come un sostegno in questo componente. Un utente potrebbe inserire un tag script nell'input e il componente che esegue il rendering di questo input eseguirà questo codice potenzialmente dannoso. In quanto tale, questo approccio ha il potenziale per introdurre vulnerabilità di scripting cross-site. Per ulteriori informazioni, fare riferimento alla documentazione ufficiale di React


4

Imposta il tipo di prop di testo su any e fai questo:

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

Esempio


3

Puoi farlo in 2 modi di cui sono a conoscenza.

1- <MyComponent text={<p>This is <strong>not</strong> working.</p>} />

E poi fallo

class MyComponent extends React.Component {
   render () {
     return (<div>{this.props.text}</div>)
   }
}

O secondo approccio fallo in questo modo

2- <MyComponent><p>This is <strong>not</strong> working.</p><MyComponent/>

E poi fallo

class MyComponent extends React.Component {
   render () {
     return (<div>{this.props.children}</div>)
   }
}

1
Ho aggiunto una variabile let vhtml = "<p>Test</p>"e l'ho usata sull'elica in questo modo text={vhtml}e per qualche motivo è ancora resa in testo normale.
Si8

2

La risposta di @matagus va bene per me, Hope below snippet è aiutato a coloro che desiderano utilizzare una variabile all'interno.

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

1

Nel mio progetto ho dovuto passare snippet html dinamico dalla variabile e renderlo all'interno del componente. Quindi ho fatto quanto segue.

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

L' oggetto defaultSelection viene passato al componente dal .jsfile

<HtmlSnippet innerHtml={defaultSelection.innerHtml} />

Componente HtmlSnippet

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

Esempio di Plunkr

reagire doc per dangerouslySetInnerHTML


1

Potresti anche usare una funzione sul componente per passare jsx a attraverso gli oggetti di scena. piace:

 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

Sì, puoi farlo usando mix array con stringhe ed elementi JSX. riferimento

<MyComponent text={["This is ", <strong>not</strong>,  "working."]} />

1

Parser da html-react-parser è una buona soluzione. Devi solo

  • installalo con npm o filato
  • import Parser da "html-react-parser";
  • chiamalo con:

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

    e funziona bene.


1

In aggiunta alla risposta: se intendi analizzare e sei già in JSX ma hai un oggetto con proprietà annidate, un modo molto elegante è usare le parentesi per forzare l'analisi JSX:

const TestPage = () => (
  <Fragment>
    <MyComponent property={
    {
      html: (
        <p>This is a <a href='#'>test</a> text!</p>
      )
    }}>
    </MyComponent>
  </Fragment>
);

1

Questa domanda ha già molte risposte, ma ho fatto qualcosa di sbagliato in relazione a questo e penso che valga la pena condividere:

Ho avuto qualcosa di simile:

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

ma il massaggio era più lungo, quindi ho provato a usare qualcosa del genere:

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

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

Mi ci è voluto un po 'per capire che mi mancava la () nella chiamata di funzione.

Non funziona

<Section message={message} />

Lavorando

<Section message={message()} />

forse questo ti aiuta, come ha fatto a me!


1

Puoi utilizzare con successo i frammenti di React per questa attività. A seconda della versione si utilizza Reagire, è possibile utilizzare la sintassi breve: <>o il tag completo: <React.Fragment>. Funziona particolarmente bene se non vuoi racchiudere l'intera stringa all'interno di tag HTML.

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

0

Possiamo fare la stessa cosa in questo modo.

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

ora vuoi inviare questo HTML all'interno di un altro componente il cui nome è Componente padre.

Chiamata: -

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

Uso del bambino: -

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

questo lavoro perfetto per me.


-9

Ho aggiunto l'html in componentDidMount utilizzando jQuery append. Questo dovrebbe risolvere il problema.

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

        return (
           <div>

           </div>
        );
    },
    componentDidMount() {
        $(ReactDOM.findDOMNode(this)).append(this.props.text);
    }
});

5
Questo è scartato perché non dovresti usare la manipolazione DOM diretta di jquery combinata con la manipolazione DOM indiretta di react, in quanto può portare al thrash del browser.
Allison
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.