2017-05-17 46 views
2

我正在處理將React組件合併到非反應環境中的項目。刪除已安裝組件的DOM元素

該項目採用骨幹,我們正在慢慢地遷移網站的某些部分反應。

我的問題:
刪除DOM節點(通過backbone/jquery)是否釋放與React組件關聯的內存?
該文檔清楚地說明,你必須管理你自己的安裝/未安裝,但是我想知道,如果簡單地移除DOM將清理內存對我來說,還是需要擔心內存泄漏的長壽命頁?

一個例子是用例離開頁面(使用我們的骨幹路由器)和重新渲染頁面,這會刪除所有以前的節點,並建立新的HTML - 這樣會發生什麼情況都安裝反應的組分?

編輯:
要清楚,我沒有用jQuery修改渲染的組件。

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) 

編輯: 調查該問題後,您必須使用MutationObserver檢測出刪除節點和卸載它們,如果你不這樣做的節點將繼續在內存中呈現。 我這裏寫了一個完整的描述:

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

+0

日誌componentWillUnmount和有我登錄它的答案 – lustoykov

+0

,它沒有運行:)但我的問題是關於內存分配,而不僅僅是生命週期方法 – Patrick

回答

2

如果刪除反應通過直接操作DOM渲染DOM節點,就會做出反應不知道這些變化。如果React組件被重新渲染,先前刪除的DOM節點將重新出現,因爲它仍然存在於Reacts虛擬DOM中。

你應該避免操縱起反應創造了DOM的部分。這可能會在應用程序中導致不需要的行爲。

例如,去除起反應呈現可能拋出以下例外DOM節點重新渲染:

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

或一些其它拋出:DOMException


下面介紹一下official documentation說有關更新DOM:

陣營不知道陣營之外的DOM所做的更改。它 決定根據自己的內部表示更新;如果 相同DOM節點由另一個庫操作,陣營得到 困惑,有沒有辦法恢復。

這並不意味着它是不可能的,甚至難於 組合反應與影響DOM的其他方式,你只需要 注意每個人在做什麼。

以避免衝突的最簡單的方法是爲了防止更新陣營部件 。您可以通過渲染React沒有 原因來更新的元素來完成此操作,如空的<div />

它繼承了React與jQuery的示例集成,here

最後,我建議您進一步閱讀虛擬DOM。官方文檔似乎沒有多說,但在網上搜索,你會發現大量的指南;如this one

+0

我看過那些文檔,但他們避免在手的確切問題。問題不在於改變React Component,而是一起移除「根節點」。我已經更新了我的問題以反映這一點,因爲我認爲它不清楚。 – Patrick

+0

@帕特里克,答案是一樣的。即使刪除根節點,React仍然「正在運行」。因此,在刪除節點並重新插入節點時,它不應該成爲問題。只要知道React將會進行任何更新,就像它從未被刪除一樣。換句話說,整個應用程序狀態將保持不變。唯一的問題是,如果React在刪除根節點時嘗試做某些事情。希望這回答你的問題? :) – Chris

+1

謝謝!就我所懷疑的而言,我想我必須稍微深入一點,以確保不會發生瘋狂的內存泄漏。 – Patrick