Wie rendert man HTML-String als echtes HTML?

Lesezeit: 9 Minuten

Benutzer-Avatar
Sergio Tapia

Hier ist, was ich versucht habe und wie es schief geht.

Das funktioniert:

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

Dies nicht:

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

Die Beschreibungseigenschaft ist nur eine normale Zeichenfolge von HTML-Inhalt. Es wird jedoch aus irgendeinem Grund als Zeichenfolge und nicht als HTML gerendert.

Geben Sie hier die Bildbeschreibung ein

Irgendwelche Vorschläge?

Benutzer-Avatar
Ilanos

Ist this.props.match.description eine Zeichenfolge oder ein Objekt? Wenn es sich um eine Zeichenfolge handelt, sollte sie problemlos in HTML konvertiert werden. Beispiel:

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

Ergebnis: http://codepen.io/ilanus/pen/QKgoLA?editors=1011

Allerdings wenn Beschreibung ist <h1 style="color:red;">something</h1> ohne die Anführungszeichen ''erhalten Sie:

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

Wenn es sich um eine Zeichenfolge handelt und Sie kein HTML-Markup sehen, ist das einzige Problem, das ich sehe, ein falsches Markup.

AKTUALISIEREN

Wenn Sie mit HTML-Entitäten zu tun haben, müssen Sie sie decodieren, bevor Sie sie an senden dangerouslySetInnerHTML deshalb heißt es “gefährlich” 🙂

Arbeitsbeispiel:

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

  • this.props.match.description ist ein String, kein Objekt. Was meinst du mit falschem Markup? Meinst du nicht geschlossene Tags? React sollte einfach nein machen?

    – Sergio Tapia

    28. September 2016 um 22:31 Uhr

  • Könnten Sie hier einfügen: console.log(this.props.match.description);

    – Ilanos

    28. September 2016 um 22:32 Uhr

  • Ein Beispiel: &lt;p&gt;&lt;strong&gt;Our Opportunity:&lt;/strong&gt;&lt;/p&gt;

    – Sergio Tapia

    28. September 2016 um 22:33 Uhr

  • In diesem Fall müssen Sie entweder .innerHTML verwenden oder HTMLEntities dekodieren.

    – Ilanos

    28. September 2016 um 22:58 Uhr

  • Mehrere Zeilen oder HTML-Code mit Tags zurückgeben: function htmlDecode(input){ var e = document.createElement(‘div’); e.innerHTML = Eingabe; var returnString = ”; for (index = 0; index < e.childNodes.length; index++) { // Fall nur eines Strings if(e.childNodes[index].nodeValue){ returnString += e.childNodes[index].nodeValue; } // Fall von HTML if(e.childNodes[index].outerHTML){ returnString += e.childNodes[index].outerHTML; } } Rückgabe ReturnString; }

    – Chris Adams

    2. Januar 2020 um 15:38 Uhr


Benutzer-Avatar
Pixelerde

Ich benutze ‘react-html-parser’

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

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

Quelle auf npmjs.com

Hervorheben des Kommentars von @okram für mehr Sichtbarkeit:

aus der Github-Beschreibung: Konvertiert HTML-Strings direkt in React-Komponenten, wodurch die Verwendung von DangerlySetInnerHTML von npmjs.com vermieden wird. Ein Dienstprogramm zum Konvertieren von HTML-Strings in React-Komponenten. Vermeidet die Verwendung von DangerlySetInnerHTML und konvertiert Standard-HTML-Elemente, -Attribute und -Inline-Stile in ihre React-Äquivalente.

  • Verwendet diese Bibliothek “dangerouslySetInnerHTML” im Hintergrund?

    – Omar

    9. Oktober 2019 um 5:51 Uhr

  • aus seiner Github-Beschreibung: Converts HTML strings directly into React components avoiding the need to use dangerouslySetInnerHTML von npmjs.com A utility for converting HTML strings into React components. Avoids the use of dangerouslySetInnerHTML and converts standard HTML elements, attributes and inline styles into their React equivalents.

    – okay

    2. Januar 2020 um 19:12 Uhr

  • Für React 17.0+ verwende ich eine ähnliche Bibliothek namens „html-react-parser“, die derzeit unterstützt wird. npmjs.com/package/html-react-parser

    – Marty McGee

    5. Februar 2021 um 14:24 Uhr

  • Aus dem FAQ-Bereich von html-react-parser: „Diese Bibliothek ist nicht XSS-sicher (Cross-Site-Scripting).“ npmjs.com/package/html-react-parser

    – Aniket Suryavanshi

    11. Mai 2021 um 10:42 Uhr

  • Möglicherweise müssen Sie mit : npm install respond-html-parser installieren

    – james.c.funk

    14. Mai 2021 um 13:52 Uhr

Benutzer-Avatar
Sergio Flores

Überprüfen Sie, ob der Text, den Sie an den Knoten anhängen möchten, nicht wie folgt maskiert ist:

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

An Stelle von:

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

Wenn Escapezeichen vorhanden sind, sollten Sie es von Ihrer Serverseite konvertieren.

Der Knoten ist Text, weil er maskiert ist

Der Knoten ist Text, weil er maskiert ist

Der Knoten ist ein Dom-Knoten, weil er nicht maskiert ist

Der Knoten ist ein Dom-Knoten, weil er nicht maskiert ist

  • Das war das Problem. Die Beschreibungszeichenfolge war HTML-Escapezeichen. Ich habe es nicht geschafft und jetzt funktioniert es gut.

    – Sergio Tapia

    29. September 2016 um 0:03 Uhr

  • Bitte vermeiden Sie die Verwendung dangerouslySetInnerHTML stattdessen verwenden Fragment von reagieren v16. Überprüfen Sie die nächste Antwort von @brad-adams

    – Kunal Parek

    22. Mai 2018 um 4:42 Uhr

  • Schätzen Sie die Erwähnung @KunalParekh, aber das sind verschiedene Dinge. Meine Antwort ist nur gültig, wenn sich das HTML in Ihrer App befindet (was bedeutet, dass es sich tatsächlich um JSX handelt). Um HTML von einer externen Quelle in jsx zu parsen, müssten Sie nach einer anderen Lösung suchen.

    – Brad Adams

    5. März 2019 um 22:42 Uhr

  • Umwandeln wie? Mit welcher API oder Paket? Die Antwort bringt Sie auf halbem Weg dorthin.

    – Zar Bomba

    20. August um 17:53 Uhr

Benutzer-Avatar
Kandarp

Wenn Sie HTML in einer Zeichenfolge haben, würde ich die Verwendung eines Pakets mit dem Namen empfehlen html-react-parser.

Installation

NPM:

npm install html-react-parser

Garn:

yarn add html-react-parser

Verwendungszweck

import parse from 'html-react-parser'
const yourHtmlString = '<h1>Hello</h1>'

Code:

<div>
    {parse(yourHtmlString)}
</div>

Wenn Sie die Kontrolle darüber haben, woher die Zeichenfolge mit HTML kommt (dh irgendwo in Ihrer App), können Sie von der neuen profitieren <Fragment> API, etwas tun wie:

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

  • In Ihrem Beispiel gibt es keine Zeichenfolge, die HTML enthält. Es ist entweder jsx oder ein einfacher String.

    – mrkvon

    19. Dezember 2018 um 18:36 Uhr

  • Nun ja, technisch gesehen hast du Recht @mrkvon, aber wie ich bereits erwähnt habe, das Lösung ist nur gültig, wenn besagtes “html”/jsx etwas ist, worüber Sie die Kontrolle haben. Nicht um etwas zu rendern roh html, das beispielsweise über eine API bereitgestellt wird. Vor dem Fragment API war immer ein Schmerz für mich, das erforderte zusätzliche span Wraps, die manchmal mit Flex-Layouts durcheinander kamen. Als ich auf diese Frage gestoßen bin und nach einer möglichen Lösung gesucht habe, dachte ich, ich würde teilen, wie ich Dinge umgangen.

    – Brad Adams

    25. Januar 2019 um 21:26 Uhr

  • Vielen Dank! Dies war die einzige Lösung, die in meinem Fall funktioniert hat. Antworten Sie auch auf mrkvons Kommentar zu dieser Antwort: Diese Antwort enthält tatsächlich HTML, dh Some text <strong>wrapped with strong</strong> enthält HTML-Tag strong.

    – Binita Bharati

    15. November 2019 um 12:39 Uhr

  • @BinitaBharati Aber das ist keine Zeichenfolge. Wenn Sie eine Zeichenfolge von einer API wie „

    Dies ist eine Zeichenfolge

    “ erhalten (oder einfach eine Zeichenfolge in einer Variablen speichern), enthält die Ausgabe beim Einfügen dieser Zeichenfolge in immer noch das < p>-Tag.

    – Muchdecal

    23. März 2020 um 22:53 Uhr

  • @BradAdams. Aber netter Trick. Ich kann die Fälle sehen, in denen es praktisch wird.

    – Muchdecal

    24. März 2020 um 18:20 Uhr

Ich verwende innerHTML zusammen mit einer Referenz, um Folgendes zu überspannen:

import React, { useRef, useEffect, useState } from 'react';

export default function Sample() {
  const spanRef = useRef<HTMLSpanElement>(null);
  const [someHTML,] = useState("some <b>bold</b>");

  useEffect(() => {
    if (spanRef.current) {
      spanRef.current.innerHTML = someHTML;
    }
  }, [spanRef.current, someHTML]);

  return <div>
    my custom text follows<br />
    <span ref={spanRef} />
  </div>
}

AKTUALISIEREN:

Ich habe einige HTML-Zustände entfernt und Kommentare hinzugefügt, um das Beispiel besser auf das Konzept abzustimmen.

/**
 * example how to retrieve a reference to an html object
 */

import React, { useRef, useEffect } from 'react';

/**
 * this component can be used into another for example <Sample/>
 */
export default function Sample() {
    /**
     * 1) spanRef is now a React.RefObject<HTMLSpanElement>
     * initially created with null value
     */
    const spanRef = useRef<HTMLSpanElement>(null);

    /**
     * 2) later, when spanRef changes because html span element with ref attribute,
     * follow useEffect hook will triggered because of dependent [spanRef].
     * in an if ( spanRef.current ) that states if spanRef assigned to valid html obj
     * we do what we need : in this case through current.innerHTML
     */
    useEffect(() => {
        if (spanRef.current) {
            spanRef.current.innerHTML = "some <b>bold</b>";
        }
    }, [spanRef]);

    return <div>
        my custom text follows<br />
        {/* ref={spanRef] will update the React.RefObject `spanRef` when html obj ready */}
        <span ref={spanRef} />
    </div>
}

  • In Ihrem Beispiel gibt es keine Zeichenfolge, die HTML enthält. Es ist entweder jsx oder ein einfacher String.

    – mrkvon

    19. Dezember 2018 um 18:36 Uhr

  • Nun ja, technisch gesehen hast du Recht @mrkvon, aber wie ich bereits erwähnt habe, das Lösung ist nur gültig, wenn besagtes “html”/jsx etwas ist, worüber Sie die Kontrolle haben. Nicht um etwas zu rendern roh html, das beispielsweise über eine API bereitgestellt wird. Vor dem Fragment API war immer ein Schmerz für mich, das erforderte zusätzliche span Wraps, die manchmal mit Flex-Layouts durcheinander kamen. Als ich auf diese Frage gestoßen bin und nach einer möglichen Lösung gesucht habe, dachte ich, ich würde teilen, wie ich Dinge umgangen.

    – Brad Adams

    25. Januar 2019 um 21:26 Uhr

  • Vielen Dank! Dies war die einzige Lösung, die in meinem Fall funktioniert hat. Antworten Sie auch auf mrkvons Kommentar zu dieser Antwort: Diese Antwort enthält tatsächlich HTML, dh Some text <strong>wrapped with strong</strong> enthält HTML-Tag strong.

    – Binita Bharati

    15. November 2019 um 12:39 Uhr

  • @BinitaBharati Aber das ist keine Zeichenfolge. Wenn Sie eine Zeichenfolge von einer API wie „

    Dies ist eine Zeichenfolge

    “ erhalten (oder einfach eine Zeichenfolge in einer Variablen speichern), enthält die Ausgabe beim Einfügen dieser Zeichenfolge in immer noch das < p>-Tag.

    – Muchdecal

    23. März 2020 um 22:53 Uhr

  • @BradAdams. Aber netter Trick. Ich kann die Fälle sehen, in denen es praktisch wird.

    – Muchdecal

    24. März 2020 um 18:20 Uhr

Benutzer-Avatar
Hou Sune

Sie verwenden einfach die DangerlySetInnerHTML-Methode von React

<div dangerouslySetInnerHTML={{ __html: htmlString }} />

Oder Sie können auf diese einfache Weise mehr implementieren: Rendern Sie den HTML-Rohinhalt in der React-App

1313720cookie-checkWie rendert man HTML-String als echtes HTML?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy