332 votes

Rendre une chaîne HTML comme du vrai HTML dans un composant React

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

Ça marche :

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

Ce n'est pas le cas :

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

La propriété description est juste une chaîne normale de contenu HTML. Cependant, pour une raison quelconque, elle est rendue comme une chaîne de caractères et non comme du HTML.

enter image description here

Des suggestions ?

250voto

Ilanus Points 3296

Fait this.props.match.description Est une chaîne ou un objet ? Si c'est une chaîne de caractères, elle devrait être convertie en HTML sans problème. 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

Toutefois, si description: <h1 style="color:red;">something</h1> sans les guillemets '' que vous allez obtenir :

​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 de caractères et que vous ne voyez pas de balisage HTML, le seul problème que je vois est un mauvais balisage.

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

76voto

Sergio Flores Points 2550

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 ça :

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

si elle s'échappe, vous devez la convertir depuis votre côté serveur.

The node is text because is escaped

Le nœud est du texte car il est échappé

The node is a dom node because isn't escaped

Le noeud est un noeud dom car il n'est pas échappé.

25voto

Brad Adams Points 923

Si vous avez le contrôle de l'endroit d'où provient la chaîne de caractères contenant du html (c'est-à-dire quelque part dans votre application), vous pouvez bénéficier de la nouvelle fonction <Fragment> API, en faisant quelque chose comme :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X