我的怀疑与在反应组件中使用计时器有关,根据我的理解一旦组件卸载,之后其所有属性/方法将不存在。
根据DOC:
componentWillUnmount()在组件出现之前立即被调用 未安装和销毁。 在此方法中执行任何必要的清理, 例如使计时器无效,取消网络请求或清除 up在componentDidMount中创建的任何DOM元素。
检查此代码段:
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {count: 1};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
3000
);
}
componentWillUnmount() {
//clearInterval(this.timerID);
}
tick() {
console.log('called', this.props.no);
}
render() {
return (
<div>
<h1>Clock {this.props.no}</h1>
</div>
);
}
}
class App extends React.Component {
constructor(){
super();
this.state = {unMount: false}
}
click(){
console.log('unmounted successfully');
this.setState({unMount: !this.state.unMount})
}
render(){
return (
<div>
<button onClick={() => this.click()}>Unmount first</button>
{!this.state.unMount && <Clock no={1}/>}
<Clock no={2}/>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='root'/>
&#13;
这里我正在渲染两个时钟组件并卸载第一个成功发生按钮的按钮,它也会更新DOM,即使在卸载第一个组件计时器后正在通过{{1正确打印道具值}}
我没有在console.log()
中清除计时器:
componentWillUmount
我怀疑是:
componentWillUnmount() {
//clearInterval(this.timerID);
}
我在计时器中传递类方法作为回调,因此一旦卸载了组件,如何存在tick函数,此计时器如何解析this.timerID = setInterval(
() => this.tick(),
3000
);
tick() {
console.log('called', this.props.no);
}
关键字和this
函数组件卸载后? tick
如何获得正确的价值?为什么它没有抛出错误:
无法读取未定义的刻度或未定义刻度
如何维护对这些功能的引用?
请帮助我在这里缺少的内容,请提供任何参考或示例。
答案 0 :(得分:4)
与C ++不同,您无法在JavaScript中显式删除内存中的对象(也称为“destroy”)。您只能删除对它们的引用。一旦没有更多引用指向对象或其属性,它就有资格进行垃圾回收。只有这样,垃圾收集器才真正摧毁它。
Memory Management — JavaScript
在这种情况下,即使在卸载后,您仍然可以在闭包中对对象及其属性进行有效引用(this.tick
,this.props
等)。在某些时候,执行后,它们将超出范围,然后您的组件将被销毁,内存将被释放。
答案 1 :(得分:1)
大量深入研究React代码,我发现以下 doc
以及来自react github页面的代码
function unmountComponentFromNode(instance, container) {
if (__DEV__) {
ReactInstrumentation.debugTool.onBeginFlush();
}
ReactReconciler.unmountComponent(
instance,
false /* safely */,
false /* skipLifecycle */,
);
if (__DEV__) {
ReactInstrumentation.debugTool.onEndFlush();
}
if (container.nodeType === DOCUMENT_NODE) {
container = container.documentElement;
}
// http://jsperf.com/emptying-a-node
while (container.lastChild) {
container.removeChild(container.lastChild);
}
}
这表明React将从UI中删除组件并为垃圾收集做好准备,但即使删除了DOM元素, 类实例不是那么方法,道具仍然存在,因此继续执行setInterval。
仅当不再使用对this.ticks()
和this.props
的引用时,它们才有资格进行垃圾回收
当事物(对象,字符串等)分配JavaScript值 创建并在不再使用时“自动”释放。 后一个过程称为垃圾收集。
答案 2 :(得分:0)
这不在react
的工作方式,更像是javascript。您应该在componentWillUnmount
上清除间隔。它甚至在文档中说:
在此方法中执行任何必要的清理,例如无效 定时器
您的代码已注释掉了吗?这不是问题吗?
componentWillUnmount() {
//clearInterval(this.timerID);
}