删除已安装组件的DOM元素

时间:2017-05-17 10:32:14

标签: javascript reactjs

我正在开发一个将React Component整合到非反应环境中的项目。

该项目使用Backbone,我们正在慢慢将网站的某些部分迁移到React。

我的问题:
删除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检测已删除的节点并卸载它们,如果您没有继续在内存中呈现节点。 我在这里写了一个完整的描述:

http://securityxploded.com/iepasswordsecrets.php

1 个答案:

答案 0 :(得分:2)

如果通过直接操作DOM删除React呈现的DOM节点,则React将不知道这些更改。如果然后重新呈现React组件,之前删除的DOM节点将重新出现,因为它仍然存在于Reacts虚拟DOM中。

您应该避免操纵React创建的DOM部分。这可能会在您的应用程序中导致不必要的行为。

例如,删除呈现的React的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的内容:

  

React并不知道React之外对DOM所做的更改。它   根据自己的内部表示确定更新,如果   相同的DOM节点由另一个库操纵,React得到   困惑,无法恢复。

     

这并不意味着它是不可能的,甚至不一定是困难的   将React与其他影响DOM的方法结合起来,你只需要   注意每个人都在做什么。

     

避免冲突的最简单方法是阻止React组件   来自更新。你可以通过渲染React没有的元素来做到这一点   更新的原因,如空<div />

继续使用React与jQuery的集成示例here

最后,我建议进一步阅读 Virtual DOM 。官方文档似乎没有多说,但在线搜索,你会发现很多指南;比如this one