2016-05-20 17 views
53

Esiste una differenza "dietro le quinte" dall'impostazione di innerHTML di un elemento rispetto all'impostazione della proprietà dangerouslySetInnerHTML su un elemento? Supponiamo che io stia correttamente igienizzando le cose per il gusto della semplicità.React.js: Set innerHTML vs dangerouslySetInnerHTML

Esempio:

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

sto facendo qualcosa di un po 'più complicata di quanto l'esempio precedente, ma l'idea generale è la stessa

risposta

97

Sì, c'è una differenza!

L'effetto immediato dell'utilizzo di innerHTML rispetto a dangerouslySetInnerHTML è identico: il nodo DOM si aggiornerà con l'HTML inserito.

Tuttavia, dietro le quinte quando si utilizza dangerouslySetInnerHTML permette Reagire sapere che il codice HTML all'interno di tale componente non è qualcosa che preoccupa.

Poiché React utilizza un DOM virtuale, quando va a confrontare il diff con il DOM effettivo, può eseguire il bypass diretto controllando i figli di quel nodo perché sa che l'HTML proviene da un'altra fonte. Quindi ci sono guadagni in termini di prestazioni.

Ancora più importante, se si utilizza semplicemente innerHTML, React non ha modo di sapere che il nodo DOM è stato modificato. La prossima volta che viene chiamata la funzione render, React sovrascriverà il contenuto che è stato iniettato manualmente con quello che ritiene essere lo stato corretto di tale nodo DOM.

La soluzione da utilizzare componentDidUpdate per garantire sempre il contenuto è sincronizzato, credo che funzionerebbe ma potrebbe esserci un flash durante ogni rendering.

+6

Ho scritto un piccolo test di valutazione non scientifico per mostrare la differenza tra l'inclusione di un file SVG e l'utilizzo di 'dangerouslySetInnerHTML': https://www.webpackbin.com/bins/-KepHa-AMxQgGxOUnAac: il metodo innerHTML è esternalizzato quasi due volte più veloce (vedi console nel webpackbin) – Joscha

+0

Questo è vero e facile da prevedere. Poiché innerHTML è un metodo nativo che associa il codice SVG direttamente al DOM senza considerare nulla. D'altra parte, pericolosamenteSetInnerHTML è il metodo che viene da React che il codice SVG deve essere analizzato come figlio React Component prima di metterli in DOM virtuale e quindi renderizzare nel DOM. – Up209d