【发布时间】:2017-12-23 02:20:31
【问题描述】:
我的疑问与在反应组件中使用计时器有关,据我了解一旦组件卸载之后,其所有属性/方法将不存在。
根据DOC:
componentWillUnmount() 在组件被调用之前立即调用 卸载并销毁。 在此方法中执行任何必要的清理, 例如使计时器无效、 取消网络请求或清理 在 componentDidMount 中创建的任何 DOM 元素。
检查这个sn-p:
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'));
<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'/>
在这里,我正在渲染两个时钟组件并卸载第一个 onclick 成功发生的按钮,并且它也在更新 DOM,即使在卸载第一个组件后,计时器正在通过 console.log() 正确打印道具值。
我没有清除componentWillUmount中的定时器:
componentWillUnmount() {
//clearInterval(this.timerID);
}
我的疑问是:
this.timerID = setInterval(
() => this.tick(),
3000
);
tick() {
console.log('called', this.props.no);
}
我在计时器中传递了一个类方法作为回调,所以一旦组件被卸载,tick 函数如何存在,这个计时器如何解析this 关键字和组件卸载后的tick 函数? this.props.no 如何具有正确的值?为什么它没有抛出错误:
无法读取未定义的刻度或未定义刻度
它是如何维护对这些函数的引用的?
帮助我在这里缺少什么,请提供任何参考或示例。
【问题讨论】:
-
..根据我的理解,一旦组件卸载,其所有属性/方法将不存在。这不太正确。从技术上讲,React 组件是一个 JS 类(函数),mounting 在这个类和相应的 DOM 东西之间建立了联系。卸载组件时,仅此连接被破坏,但相应的 JS 类及其道具/方法仍然存在。
-
@hindmost 谢谢,但是如果该代码仍然存在,那么它应该会产生内存问题,因为当我们访问不同的页面时组件会非常频繁地渲染和卸载,对吗?另一件事是,直到什么时候该代码才可用,因为我等了 10 分钟,但仍然可以正确打印值,一段时间后它应该会抛出错误。
标签: javascript reactjs