Wie parse ich HTML in die React-Komponente?

Lesezeit: 6 Minuten

Benutzer-Avatar
Singen

Das ist mein Senario:
1. Anwendung fordert CMS (Content Management System) für Seiteninhalte an.
2. CMS-Rückgabe "<div>Hi,<SpecialButton color="red">My Button</SpecialButton></div>"

3. Die Anwendung konsumiert den Inhalt, rendert die entsprechende Komponente mit den im Attribut bereitgestellten Daten.

Ich kann nicht herausfinden, wie es geht Schritt 3 Bei React ist jeder Ratschlag willkommen.

Danke @Glenn Reyes, hier ist ein Sandkasten um das Problem zu zeigen.

import React from 'react';
import { render } from 'react-dom';

const SpecialButton = ({ children, color }) => (
  <button style={{color}}>{children}</button>
);

const htmlFromCMS = `
<div>Hi, 
  <SpecialButton color="red">My Button</SpecialButton>
</div>`;

const App = () => (
  <div dangerouslySetInnerHTML={{__html: htmlFromCMS}}>
  </div>
);

// expect to be same as
// const App = () => (
//   <div>Hi, 
//     <SpecialButton color="red">My Button</SpecialButton>
//   </div>
// );

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

Hier ist eine Live-Demo hergestellt von Vuejs. Schnur "<div v-demo-widget></div>" könnte als Vuejs-Anweisung behandelt und gerendert werden. Quellcode.

  • Ich habe keine endgültige Antwort für Sie, Andy, kann Ihnen aber möglicherweise eine Richtung weisen, je nachdem, wie Sie die CMS-Daten erhalten. Haben Sie versucht, eine Komponente höherer Ordnung zu verwenden, um diejenige zu rendern, die von der Anfrage zurückkommt? Ich denke, eine Komponente, die dann Ihre angeforderte Komponente rendert, könnte der richtige Weg sein.

    – Brett Osten

    20. Juni 2017 um 4:59 Uhr

  • @BrettEast, eine Komponente höherer Ordnung könnte die Anfrage ausführen, aber mein Problem besteht darin, die Zeichenfolge wie zu erhalten <h4>Hello</h4><reactcomponenct attr1="foo"></mycomponenct> von CMS, wie man das Teil reagieren lässt <reactcomponenct attr1="foo"></mycomponenct> Komponente ist, muss der Code der Komponente ausgeführt werden.

    – Singen

    20. Juni 2017 um 8:21 Uhr

  • Ja, das ist knifflig. Gibt es eine Chance, dass Ihre eingehenden Daten React-Benennungsmustern folgen, mit einem Großbuchstaben für React-Komponenten und Kleinbuchstaben für HTML-Elemente? Vielleicht könnte eine Regex den Trick machen?

    – Brett Osten

    20. Juni 2017 um 8:25 Uhr

  • Ja, ich denke, es ist in Ordnung, Namensmustern zu folgen, aber es sieht so aus, als müsste ich einen Compiler schreiben, um so etwas wie eine Winkeldirektive zu tun …

    – Singen

    20. Juni 2017 um 8:57 Uhr

Wie in dieser Antwort von EsterlingAccimeYoutuber erwähnt, können Sie a verwenden parser falls Sie es nicht verwenden möchten dangerouslySetInnerHTML Attribut.

Inzwischen, react-html-parser wurde seit 3 ​​Jahren nicht mehr aktualisiert, also habe ich mich nach einem anderen Modul umgesehen.

html-react-parser macht die gleiche Arbeit, wird aber regelmäßig gewartet und aktualisiert.

Es sollte eine gute Praxis sein, Ihre zu desinfizieren html-String zu verhindern XSS Anschläge. dompurify kann dafür verwendet werden.

Ich habe das Codebeispiel von EsterlingAccimeYoutuber wie folgt aktualisiert:

import React from 'react';
import { render } from 'react-dom';
import parse from 'html-react-parser';
import DOMPurify from 'dompurify';

const SpecialButton = ({ children, color }) => (
  <button style={{color}}>{children}</button>
);

const htmlFromCMS = `
<div>Hi, 
  <SpecialButton color="red">My Button</SpecialButton>
</div>`;

const htmlFrom = (htmlString) => {
        const cleanHtmlString = DOMPurify.sanitize(htmlString,
          { USE_PROFILES: { html: true } });
        const html = parse(cleanHtmlString);
        return html;
}

const App = () => (
  <div>
     {htmlFromCMS && htmlFrom(htmlFromCMS)}
  </div>
);


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

Inspiriert durch den obigen Originalbeitrag, daher besonderer Dank an die Originalautoren!

  • Danke für den Hinweis auf die gut gepflegte Bibliothek html-react-parser anstatt react-html-parser.

    – Daniel Loureiro

    26. Juni 2021 um 20:27 Uhr

Für jede zukünftige Erweiterung von GProst Answer können Sie ReactDOMserver verwenden. So können wir dasselbe implementieren.

import React from "react";
import { render } from "react-dom";
import { renderToString } from "react-dom/server";

const SpecialButton = ({ children, color }) => (
  <button style={{ color }}>{children}</button>
);

const renderButton = renderToString(<SpecialButton>MyButton</SpecialButton>);

const htmlFromCMS = `
<div>Hi, 
  ${renderButton}
</div>`;

const App = () => <div dangerouslySetInnerHTML={{ __html: htmlFromCMS }} />;

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

  • Verwendet diese Bibliothek “dangerouslySetInnerHTML” im Hintergrund?

    – Omar

    9. Oktober 2019 um 5:21 Uhr

  • react-html-parser verwendet nicht dangerouslySetInnerHTML im Hintergrund; es benutzt htmlparser2.

    – kca

    15. Juli 2020 um 12:09 Uhr

  • Die Sache ist, dass es die Schaltfläche selbst nicht gerendert hat. Ich hatte stattdessen ein spezielles Schaltflächen-HTML-Element. Die Komponente wurde nicht gerendert. <specialbutton color="red">My Button</specialbutton>

    – Alexej Jaremenko

    12. März 2021 um 12:37 Uhr


  • @AlekseyYaremenko Für benutzerdefinierte Komponenten müssen Sie die verwenden transform Möglichkeit: github.com/peternewnham/react-html-parser/issues/…

    – Daniel Loureiro

    26. Juni 2021 um 20:24 Uhr

Sie können versuchen, es zu verwenden ReactDOMserver zu rendern <MyReactComponent /> hinein html auf Ihrem Server und übergeben Sie es dann an den Client, wo Sie alle empfangenen einfügen können html über dangerouslySetInnerHTML.

  • Entsprechend ReactDOMServer, RenderToString akzeptiere a component als Parameter kein String wie ““, daher konnte es nicht korrekt gerendert werden.

    – Singen

    20. Juni 2017 um 8:16 Uhr


  • Sicher, zuerst müssen Sie die entsprechende Klasse anhand des Komponentennamens finden. Und dann rendern. Ich gehe davon aus, dass es für Sie einfach sein wird, dies auf der Serverseite (im CMS) zu tun. Andernfalls müssen Sie die gesamte Zeichenfolge analysieren, reines HTML und die React-Komponente trennen und sie dann zusammen in einer anderen Komponente rendern. Wie auch immer, das ist keine triviale Aufgabe, ich schlage vor, Sie finden eine Problemumgehung.

    – GProst

    20. Juni 2017 um 8:38 Uhr

  • Ich verstehe, also ist Ihr Vorschlag, dass die Komponentenlogik in CMS eingefügt wird und CMS die gerenderte Komponentenzeichenfolge richtig zurückgibt?

    – Singen

    20. Juni 2017 um 8:59 Uhr

  • Ja, das größte Problem besteht darin, die Zeichenfolge zu analysieren. Wenn Sie den Komponentennamen ohne große Schwierigkeiten im CMS abrufen können, ist es einfacher, die Komponente im CMS zu rendern und sie dann an den Client zurückzugeben.

    – GProst

    20. Juni 2017 um 9:08 Uhr

  • Sieht so aus, als ob ich es im Client oder im CMS mache, ich brauche einen Parser aus HTML, um die Komponente zu reagieren

    – Singen

    20. Juni 2017 um 10:52 Uhr

  • Entsprechend ReactDOMServer, RenderToString akzeptiere a component als Parameter kein String wie ““, daher konnte es nicht korrekt gerendert werden.

    – Singen

    20. Juni 2017 um 8:16 Uhr


  • Sicher, zuerst müssen Sie die entsprechende Klasse anhand des Komponentennamens finden. Und dann rendern. Ich gehe davon aus, dass es für Sie einfach sein wird, dies auf der Serverseite (im CMS) zu tun. Andernfalls müssen Sie die gesamte Zeichenfolge analysieren, reines HTML und die React-Komponente trennen und sie dann zusammen in einer anderen Komponente rendern. Wie auch immer, das ist keine triviale Aufgabe, ich schlage vor, Sie finden eine Problemumgehung.

    – GProst

    20. Juni 2017 um 8:38 Uhr

  • Ich verstehe, also ist Ihr Vorschlag, dass die Komponentenlogik in CMS eingefügt wird und CMS die gerenderte Komponentenzeichenfolge richtig zurückgibt?

    – Singen

    20. Juni 2017 um 8:59 Uhr

  • Ja, das größte Problem besteht darin, die Zeichenfolge zu analysieren. Wenn Sie den Komponentennamen ohne große Schwierigkeiten im CMS abrufen können, ist es einfacher, die Komponente im CMS zu rendern und sie dann an den Client zurückzugeben.

    – GProst

    20. Juni 2017 um 9:08 Uhr

  • Sieht so aus, als ob ich es im Client oder im CMS mache, ich brauche einen Parser aus HTML, um die Komponente zu reagieren

    – Singen

    20. Juni 2017 um 10:52 Uhr

1005640cookie-checkWie parse ich HTML in die React-Komponente?

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

Privacy policy