当弹出窗口关闭时,如何删除扩展弹出窗口(React 组件)的侦听器?

我有一个使用 react(遗留代码)构建的扩展,并且我一直在跟踪一个我最终解决的错误,但我无法修复。


当扩展的图标(在浏览器栏中)被点击时,一个 reactComponent被创建,并且一个监听器被添加到它的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,

 })

}

这样,至少,它只被调用了一次。但是,我担心我的组件被多次创建并消耗浏览器中的内存。


我如何确保组件实际上正在被销毁?如何检测弹出窗口何时关闭以删除事件?


慕运维8079593
浏览 147回答 1
1回答

收到一只叮咚

可以为此使用chrome.runtime.onConnect(感谢@wOxxOm):在 React 组件的构造函数中打开一个连接:  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');   })})在我看来,这不是很优雅,但它确实有效。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript