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