【问题标题】:React event listener with throttle not being removed反应事件侦听器没有被移除油门
【发布时间】:2018-02-16 13:39:32
【问题描述】:

我的代码如下所示:

componentDidMount() {
    window.addEventListener('resize', this.resize);
}

componentWillUnmount() {
    window.removeEventListener('resize', this.resize);
}

resize = () => this.forceUpdate();

这很好用。但后来我尝试添加一个油门以获得更好的性能

componentDidMount() {
    window.addEventListener('resize', _.throttle(this.resize, 200));
}

componentWillUnmount() {
    window.removeEventListener('resize', this.resize);
}

resize = () => this.forceUpdate();

但是当我在不同的视图中调整屏幕大小时,我收到了这个错误警告:

Warning: forceUpdate(...): Can only update a mounted or mounting component. This usually means you called forceUpdate() on an unmounted component. This is a no-op. Please check the code for the component.

这意味着我没有正确删除监听器。如何删除带有节流阀的侦听器?还是应该把油门放在别的地方?

我尝试更新componentWillUnmount 喜欢这个:

componentWillUnmount() {
    window.removeEventListener('resize', _.throttle(this.resize, 200));
}

但这也不起作用。

任何想法

【问题讨论】:

    标签: javascript reactjs addeventlistener throttling


    【解决方案1】:

    也许你可以在构造函数中设置油门:

    constructor(props) {
       ...
       this.throttledResize = _.throttle(this.resize, 200)
    }
    
    componentDidMount() {
        window.addEventListener('resize', this.throttledResize);
    }
    
    componentWillUnmount() {
        window.removeEventListener('resize', this.throttledResize);
    }
    

    要详细说明为什么这样做,window.removeEventListener 必须查看目标和事件的所有已注册事件侦听器,并对传递给它的事件处理程序进行相等性检查 - 如果找到匹配项,则删除它。这是一个简单的实现:

    window.removeEventListener = function(event, handler) {
       // remove the supplied handler from the registered event handlers
       this.eventHandlers[event] = this.eventHandlers[event].filter((evtHandler) => {
           return evtHandler !== handler;
       })
    }
    

    _.throttle 每次运行都会返回一个新函数;因此,相等性检查将始终失败,您将无法删除事件侦听器(不删除 all 事件侦听器)。以下是相等检查中发生的事情的简单演示:

    function foo() {}
    function generateFunction() { 
       // just like throttle, this creates a new function each time it is called
       return function() {} 
    }
    
    console.log(foo === foo) // true
    console.log(generateFunction() === generateFunction()) // false

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-10
      • 2017-03-16
      • 2022-01-16
      • 2018-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多