web-dev-qa-db-fra.com

Rendre une chaîne HTML sous forme de code HTML réel dans un composant React

Voici ce que j'ai essayé et comment ça se passe mal.

Cela marche:

<div dangerouslySetInnerHTML={{ __html: "<h1>Hi there!</h1>" }} />

Cela ne veut pas:

<div dangerouslySetInnerHTML={{ __html: this.props.match.description }} />

La propriété description est simplement une chaîne de contenu HTML normale. Cependant, il est rendu sous forme de chaîne, et non HTML pour une raison quelconque.

enter image description here

Aucune suggestion?

91
Sergio Tapia

Vérifiez si le texte que vous essayez d'ajouter au nœud n'est pas échappé comme ceci:

var prop = {
    match: {
        description: '&lt;h1&gt;Hi there!&lt;/h1&gt;'
    }
};

Au lieu de cela:

var prop = {
    match: {
        description: '<h1>Hi there!</h1>'
    }
};

si est échappé, vous devez le convertir depuis votre serveur.

The node is text because is escaped

Le nœud est du texte car échappé

The node is a dom node because isn't escaped

Le nœud est un nœud dom car il n'est pas échappé

26
Sergio Flores

Est-ce que this.props.match.description est une chaîne ou un objet? Si c'est une chaîne, elle devrait être convertie correctement en HTML. Exemple:

class App extends React.Component {

constructor() {
    super();
    this.state = {
      description: '<h1 style="color:red;">something</h1>'
    }
  }

  render() {
    return (
      <div dangerouslySetInnerHTML={{ __html: this.state.description }} />
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));

Résultat: http://codepen.io/ilanus/pen/QKgoLA?editors=1011

Cependant, si description: <h1 style="color:red;">something</h1> sans les guillemets '', vous obtiendrez:

​Object {
$$typeof: [object Symbol] {},
  _owner: null,
  key: null,
  props: Object {
    children: "something",
    style: "color:red;"
  },
  ref: null,
  type: "h1"
}

Si c'est une chaîne et que vous ne voyez aucune balise HTML, le seul problème que je vois est une balise incorrecte.

UPDATE

Si vous avez affaire à HTMLEntitles. Vous devez les décoder avant de les envoyer à dangerouslySetInnerHTML c'est pourquoi ils l'ont appelé dangereusement :)

Exemple de travail:

class App extends React.Component {

  constructor() {
    super();
    this.state = {
      description: '&lt;p&gt;&lt;strong&gt;Our Opportunity:&lt;/strong&gt;&lt;/p&gt;'
    }
  }

   htmlDecode(input){
    var e = document.createElement('div');
    e.innerHTML = input;
    return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
  }

  render() {
    return (
      <div dangerouslySetInnerHTML={{ __html: this.htmlDecode(this.state.description) }} />
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
64
Ilanus

J'ai utilisé 'react-html-parser'

yarn add react-html-parser
import ReactHtmlParser from 'react-html-parser'; 

<div> { ReactHtmlParser (html_string) } </div>

Source sur npmjs.com

12
pixelearth

Si vous avez le contrôle sur l'origine de la chaîne contenant le code HTML (c'est-à-dire quelque part dans votre application), vous pouvez bénéficier de la nouvelle API <Fragment> en procédant comme suit:

import React, {Fragment} from 'react'

const stringsSomeWithHtml = {
  testOne: (
    <Fragment>
      Some text <strong>wrapped with strong</strong>
    </Fragment>
  ),
  testTwo: `This is just a plain string, but it'll print fine too`,
}

...

render() {
  return <div>{stringsSomeWithHtml[prop.key]}</div>
}
10
Brad Adams