Javascript 当弹出窗口关闭时,如何删除扩展弹出窗口(React组件)的侦听器?
我有一个使用react(遗留代码)构建的扩展,我一直在跟踪一个我最终解决的bug,但我无法修复 单击扩展的图标(在浏览器栏中)时,将创建一个reactJavascript 当弹出窗口关闭时,如何删除扩展弹出窗口(React组件)的侦听器?,javascript,reactjs,google-chrome-extension,firefox-addon,Javascript,Reactjs,Google Chrome Extension,Firefox Addon,我有一个使用react(遗留代码)构建的扩展,我一直在跟踪一个我最终解决的bug,但我无法修复 单击扩展的图标(在浏览器栏中)时,将创建一个react组件,并在其componentDidMount()中添加一个侦听器: 但是,我不知道如何在组件消失后删除侦听器,例如单击浏览器中的其他位置。我原以为componentWillUnmount是我要找的,但它从未被调用: componentWillUnmount(){ // this is never called!!! background_
组件
,并在其componentDidMount()
中添加一个侦听器:
但是,我不知道如何在组件
消失后删除侦听器,例如单击浏览器中的其他位置。我原以为componentWillUnmount
是我要找的,但它从未被调用:
componentWillUnmount(){
// this is never called!!!
background_object.event.removeListener('onDance', this.dance);
}
问题是每次我打开(并关闭)扩展弹出窗口时,一个新事件会添加到background\u对象
,因此dance()
会被多次调用(只要我打开并关闭弹出窗口)
现在,我已经使用了一次,而不是上的:
async componentDidMount(){
...
// an object from the background is retrieved
let background_object = this.props.getBackgroundObject();
...
// code including await background_object.doSomething();
...
// add event (eventemitter3 is used for the event management)
background_object.event.once('onMusic', this.dance);
...
}
async dance() {
// add the event again in case onMusic is called again
background_object.event.once('onMusic', this.dance);
this.setState({
'music': true,
})
}
这样,至少只调用一次。但是,我担心我的组件被多次创建,并且在浏览器中消耗内存
我如何才能确保组件确实被销毁?如何检测弹出窗口何时关闭以删除事件?可以使用chrome.runtime.onConnect
(感谢@wOxxOm):
在React组件的构造函数中打开一个连接:
在react组件的componentDidMount
中添加事件
在后台的某个位置(例如background.js
)侦听与浏览器的连接,并在连接丢失时删除事件:
在我看来,这不是很优雅,但它正在发挥作用。为什么函数是异步的?我认为问题可能与此有关。应调用componentWillUnmount。卸载时删除侦听器的方法是正确的。弹出窗口将立即终止,因此不会运行卸载代码。改为在后台脚本中使用虚拟端口连接。@oshell,它是异步的,因为在…
部分中有一些等待函数。我读过这篇文章,这很正常(正如我所说的,这是遗留代码,所以不能给你一个完整的答案)@wOxxOm,这似乎是一个解决方案(有点道理,除非我期待React会有更优雅的表现)。我将在几个小时后尝试,并发布结果。那么,组件将卸载
的目的是什么?可能它只是不适用于扩展?弹出窗口会立即终止,因此不会运行卸载/卸载代码。
async componentDidMount(){
...
// an object from the background is retrieved
let background_object = this.props.getBackgroundObject();
...
// code including await background_object.doSomething();
...
// add event (eventemitter3 is used for the event management)
background_object.event.once('onMusic', this.dance);
...
}
async dance() {
// add the event again in case onMusic is called again
background_object.event.once('onMusic', this.dance);
this.setState({
'music': true,
})
}
constructor(props){
super(props)
this.state = {
dance: false,
}
...
var port = this.xbrowser.runtime.connect();
...
}
async componentDidMount(){
...
// an object from the background is retrieved
let background_object = this.props.getBackgroundObject();
...
// add event (eventemitter3 is used for the event management)
background_object.event.on('onMusic', this.dance);
...
}
async dance() {
this.setState({
'music': true,
})
}
chrome.runtime.onConnect.addListener(function (externalPort) {
externalPort.onDisconnect.addListener(function () {
let background_object = this.props.getBackgroundObject();
background_object.event.removeListener('onSend');
})
})