我有一个使用react(旧版代码)构建的扩展,并且我一直在跟踪一个我最终陷入困境的错误,但是我无法修复。
单击扩展程序的图标(在浏览器栏中)时,将创建一个反应Component
,并在其componentDidMount()
中添加一个侦听器:
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.on('onMusic', this.dance);
...
}
async dance() {
this.setState({
'music': true,
})
}
但是,一旦Component
消失,例如通过单击浏览器中的其他位置。我以为componentWillUnmount
是我要寻找的东西,但是它从未被称为:
componentWillUnmount(){
// this is never called!!!
background_object.event.removeListener('onDance', this.dance);
}
问题是每次我打开(和关闭)扩展弹出窗口时,都会向background_object
中添加一个新事件,因此dance()
被多次调用(与我打开和关闭时一样多)。关闭弹出窗口。
目前,我使用的是once
而不是on
:
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,
})
}
至少这样,它仅被调用一次。但是,我担心我的组件被多次创建并占用了我的浏览器中的内存。
如何确定该组件实际上已被销毁?如何检测何时关闭弹出窗口以删除事件?
答案 0 :(得分:0)
为此可以使用chrome.runtime.onConnect
(感谢@wOxxOm):
constructor(props){
super(props)
this.state = {
dance: false,
}
...
var port = this.xbrowser.runtime.connect();
...
}
componentDidMount
中。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,
})
}
background.js
)监听与浏览器的连接,并在连接丢失时删除事件:chrome.runtime.onConnect.addListener(function (externalPort) {
externalPort.onDisconnect.addListener(function () {
let background_object = this.props.getBackgroundObject();
background_object.event.removeListener('onSend');
})
})
在我的脑海中,这不是很优雅,但是可以解决问题。