Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 当弹出窗口关闭时,如何删除扩展弹出窗口(React组件)的侦听器?_Javascript_Reactjs_Google Chrome Extension_Firefox Addon - Fatal编程技术网

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

Javascript 当弹出窗口关闭时,如何删除扩展弹出窗口(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_

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

单击扩展的图标(在浏览器栏中)时,将创建一个react
组件
,并在其
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'); 
      })
    })