为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕运维8079593 2021-12-23 16:21:33
我有一个使用 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, })}这样,至少,它只被调用了一次。但是,我担心我的组件被多次创建并消耗浏览器中的内存。我如何确保组件实际上正在被销毁?如何检测弹出窗口何时关闭以删除事件?
查看完整描述

1 回答

?
收到一只叮咚

TA贡献1821条经验 获得超4个赞

可以为此使用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'); 

  })

})

在我看来,这不是很优雅,但它确实有效。


查看完整回答
反对 回复 2021-12-23
  • 1 回答
  • 0 关注
  • 146 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信