React.js: Setze innerHTML gegen gefährlichSetInnerHTML

171

Gibt es einen Unterschied "hinter den Kulissen" zwischen dem Festlegen der innerHTML eines Elements und dem Festlegen der Eigenschaft gefährliche.SetInnerHTML für ein Element? Angenommen, ich desinfiziere die Dinge der Einfachheit halber ordnungsgemäß.

Beispiel:

var test = React.createClass({
  render: function(){
    return (
      <div contentEditable='true' dangerouslySetInnerHTML={{ __html: "Hello" }}></div>
    );
  }
});

vs.

var test = React.createClass({
  componentDidUpdate: function(prevProp, prevState){
    this.refs.test.innerHTML = "Hello";
  },
  render: function(){
    return (
      <div contentEditable='true' ref='test'></div>
    );
  }
});

Ich mache etwas etwas komplizierteres als das obige Beispiel, aber die Gesamtidee ist dieselbe

Jshoe523
quelle

Antworten:

236

Ja, da gibt es einen Unterschied!

Der unmittelbare Effekt der Verwendung von innerHTMLversus dangerouslySetInnerHTMList identisch - der DOM-Knoten wird mit dem injizierten HTML aktualisiert.

Doch hinter den Kulissen wenn Sie dangerouslySetInnerHTMLes wissen lässt, Reagieren , dass das HTML innerhalb dieser Komponente nicht etwas , geht es darum , sich interessiert.

Da React ein virtuelles DOM verwendet, kann es beim Vergleichen des Diff mit dem tatsächlichen DOM die Überprüfung der untergeordneten Elemente dieses Knotens umgehen, da es weiß, dass der HTML-Code von einer anderen Quelle stammt . Es gibt also Leistungssteigerungen.

Noch wichtiger ist , wenn Sie einfach verwenden innerHTML, hat React keine Möglichkeit zu wissen, dass der DOM-Knoten geändert wurde. Beim nächsten renderAufruf der Funktion überschreibt React den manuell eingefügten Inhalt mit dem, was seiner Meinung nach der korrekte Status dieses DOM-Knotens sein sollte.

Ihre Lösung, um componentDidUpdatesicherzustellen, dass der Inhalt immer synchron ist, würde meiner Meinung nach funktionieren, aber bei jedem Rendern kann es zu einem Flash kommen.

Francis John
quelle
11
Ich habe einen kleinen, nicht wissenschaftlichen Perfektionstest geschrieben, um den Unterschied zwischen dem Inlining eines SVG und der Verwendung von dangerouslySetInnerHTML: webpackbin.com/bins/-KepHa-AMxQgGxOUnAac - zeigt, dass die innerHTML-Methode fast doppelt so schnell ist (siehe Konsole im Webpackbin)
Joscha
4
Das ist wahr und leicht vorherzusagen. Da innerHTML eine native Methode ist, die den SVG-Code direkt an das DOM bindet, ohne etwas zu berücksichtigen. Auf der anderen Seite ist gefährlichSetInnerHTML die Methode von React, bei der der SVG-Code als untergeordnete Komponenten der Reaktionskomponente analysiert werden muss, bevor sie in das virtuelle DOM gestellt und dann in das DOM gerendert werden.
Up209d
3

Laut Dangerously Set innerHTML ,

Durch unsachgemäße Verwendung der innerHTMLDose können Sie einen XSS- Angriff (Cross-Site Scripting) ausführen. Die Bereinigung von Benutzereingaben für die Anzeige ist bekanntermaßen fehleranfällig, und eine nicht ordnungsgemäße Bereinigung ist eine der Hauptursachen für Web-Schwachstellen im Internet.

Unsere Designphilosophie ist, dass es "einfach" sein sollte, Dinge sicher zu machen, und Entwickler sollten ihre Absicht ausdrücklich angeben, wenn sie "unsichere" Vorgänge ausführen. Der Requisitenname wurde dangerouslySetInnerHTMLabsichtlich als erschreckend gewählt, und der Requisitenwert (ein Objekt anstelle einer Zeichenfolge) kann verwendet werden, um bereinigte Daten anzuzeigen.

Nachdem Sie die Sicherheitsauswirkungen vollständig verstanden und die Daten ordnungsgemäß bereinigt haben, erstellen Sie ein neues Objekt, das nur den Schlüssel __htmlund Ihre bereinigten Daten als Wert enthält. Hier ist ein Beispiel mit der JSX-Syntax:

function createMarkup() {
    return {
       __html: 'First &middot; Second'    };
 }; 

<div dangerouslySetInnerHTML={createMarkup()} /> 

Lesen Sie mehr darüber unter folgendem Link:

Dokumentation : Reagieren Sie auf DOM-Elemente - gefährlichSetInnerHTML .

Ganesh Sanap
quelle
1
Dies beantwortet die Frage nicht.
Quentin
2

Basierend auf ( gefährlichSetInnerHTML ).

Es ist eine Requisite, die genau das macht, was Sie wollen. Sie nennen es jedoch, um zu vermitteln, dass es mit Vorsicht verwendet werden sollte

Jason
quelle
1
Nun,