【发布时间】:2019-01-04 04:17:42
【问题描述】:
我有一个 React 组件,其中包含如下代码:
class MyComponent extends React.Component {
// ...
trackStats = false
componentDidMount() {
this.monitorActivity()
}
componentWillUnmount() {
this.trackStats = false
}
async monitorActivity() {
this.trackStats = true
while (this.trackStats && this.elRef.current) {
// elRef is a React ref to a DOM element rendered in render()
await Promise.race([
nextEvent(this.elRef.current, 'keydown'),
nextEvent(this.elRef.current, 'click'),
nextEvent(this.elRef.current, 'mousemove'),
nextEvent(this.elRef.current, 'pointermove'),
])
this.logUserActivity()
}
}
logUserActivity() {
// ...
}
render() { /* ... */ }
}
const nextEvent = (target, eventName) => new Promise(resolve => {
target.addEventListener(eventName, resolve, { once: true })
})
问题是,如果这个组件被卸载,那么添加到 this.elRef.current 引用的 DOM 元素上的事件处理程序将保留在内存中,因为用户将不再与不再存在的元素交互DOM。
所以 while 循环将一直等待下一个事件,这永远不会发生,并且因为 while 循环仍在等待最后一个事件,我相信这会导致 MyComponent 的实例被泄露记忆。
或者引擎是否足够聪明来清理它?如果我没有对这些东西的任何可访问的引用,并且唯一链接的是while循环的范围,它正在等待一些承诺履行,引擎会丢弃它吗?或者它会让 while 循环范围运行,等待 Promise?
如果 while 循环仍然存在(我猜它确实存在),我应该如何清理它?
【问题讨论】:
标签: javascript reactjs typescript memory-leaks code-cleanup