2017-05-17 4 views
2

Ich arbeite an einem Projekt, das React Component in eine NON-react-Umgebung integriert.Entfernen eines DOM-Elements einer eingehängten Komponente

Das Projekt verwendet Backbone und wir migrieren langsam einige Teile der Website zu React.

Meine Frage:
Wird durch Entfernen eines DOM-Knotens (durch Backbone/Jquery) der mit der React-Komponente verbundene Speicher freigegeben?
Die Dokumentation besagt eindeutig, dass Sie Ihre eigenen Mounting/Un-Mounting verwalten müssen, aber ich frage mich, ob das Entfernen des DOM den Speicher für mich aufräumen wird, oder muss ich mich über Speicherlecks in einem langlebigen sorgen Seite?

ein Beispiel usecase navigiert (mit unserem Backbone-Router) und re-rendering die Seite, das entfernt alle vorherigen Knoten und baut neue html - Was passiert also mit allen montierten react-Komponenten?

Bearbeiten:
Um klar zu sein, ich bin nicht eine gerenderte Komponente mit jQuery ändern.

class App extends React.Component{ 
    render(){ 
     return (<div>Amazing</div>); 
    } 
} 



//extreme use case, render a component, remove the DOM node, create a new DOM node 
setInterval(function(){ 
    ReactDOM.render(React.createElement(App),document.getElementById('app')); 
    $('#app').remove(); 
    $('body').append($('<div id="app">')); 
},250) 

Edit: Nachdem das Problem zu untersuchen, müssen Sie entfernten Knoten erkennen MutationObserver verwenden und aushängen ihnen, wenn Sie die Knoten im Speicher zu erbringenden nicht tun wird fortgesetzt. Ich schrieb eine vollständige Beschreibung hier:

https://medium.com/@patrick.tolosa/backbone-router-with-react-components-13791727a351

+0

Log-KomponenteWillUnmount und es gibt die Antwort – lustoykov

+0

Ich loggte es, es läuft nicht :) aber meine Frage ist über Speicherzuweisung und nicht nur die Lebenszyklus-Methode – Patrick

Antwort

2

Wenn Sie einen DOM-Knoten entfernen, die direkt gerendert reagieren, indem sie die DOM-Manipulation, Reaktion wird nicht dieser Veränderungen kennen. Wenn die React-Komponente dann erneut gerendert wird, wird der zuvor entfernte DOM-Knoten erneut angezeigt, da er noch in Reacts virtual DOM vorhanden ist.

Sie sollten vermeiden, die Teile des DOM zu manipulieren, die React erstellt hat. Dies kann zu unerwünschtem Verhalten in Ihrer Anwendung führen.

Um zum Beispiel einen DOM-Knoten zu entfernen, die wiedergegeben reagieren, um die folgende Ausnahme werfen kann wieder machen:

Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node. 

oder eine andere DOMException.


Hier ist, was die official documentation sagt über die DOM-Aktualisierung:

Reagieren nicht bewusst Änderungen an den DOM außerhalb von React hergestellt ist. Es bestimmt Updates basierend auf seiner eigenen internen Darstellung, und wenn die gleichen DOM-Knoten von einer anderen Bibliothek manipuliert werden, wird React verwirrt und hat keine Möglichkeit zur Wiederherstellung. Dies bedeutet nicht, dass es unmöglich oder sogar notwendig schwierig ist, kombinieren Reagieren mit anderen Möglichkeiten, das DOM zu beeinflussen, müssen Sie nur auf achten, was jeder tut.

Die einfachste Möglichkeit, Konflikte zu vermeiden, besteht darin, zu verhindern, dass die React-Komponente aktualisiert wird. Sie können dies tun, indem Sie Elemente rendern, die React keinen Grund hat, um zu aktualisieren, wie eine leere <div />.

Es geht weiter mit einer Beispielintegration von React mit jQuery, here.

Schließlich schlage ich weiterlesen auf die Virtual DOM. Die offizielle Dokumentation scheint nicht viel zu sagen, aber suchen Sie online und Sie werden eine Fülle von Leitfäden finden; wie this one.

+0

Ich habe diese Dokumente gelesen, aber sie vermeiden die genaue Frage zur Hand. Das Problem besteht nicht darin, eine React-Komponente zu ändern, sondern den Wurzelknoten alle zusammen zu entfernen. Ich habe meine Frage aktualisiert, um dies zu reflektieren, da ich denke, dass es unklar war. – Patrick

+0

@Patrick, die Antwort ist die gleiche. Reagieren läuft immer noch, selbst wenn Sie den Root-Knoten entfernen. Während das Entfernen nicht "ideal" ist, sollte es kein Problem sein, wenn Sie den Knoten entfernen und ihn erneut einfügen. Sie sollten wissen, dass React alle Aktualisierungen so durchführt, als ob sie nie entfernt würden. Mit anderen Worten, der gesamte Anwendungszustand bleibt erhalten. Das einzige Problem wird auftreten, wenn React versucht, etwas zu tun, während der Root-Knoten entfernt wird. Hoffe das beantwortet deine Frage? :) – Chris

+1

Danke! Soweit ich es vermutet habe, muss ich mich wohl ein bisschen tiefer profilieren, um sicherzustellen, dass keine verrückten Speicherlecks auftreten. – Patrick

Verwandte Themen