javascript - react 事件监听器, throttle 未被删除

标签 javascript reactjs addeventlistener throttling

我的代码看起来像这样:

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

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

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

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

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

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

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

但是当我在不同的 View 中调整屏幕大小时,我收到此错误警告:

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.

这意味着我没有正确移除监听器。如何删除带有 throttle 的监听器?或者我应该把 throttle 放在别的地方吗?

我尝试像这样更新 componentWillUnmount:

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

但这也不起作用。

任何想法

最佳答案

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

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 每次运行都会返回一个新函数;因此,相等性检查将始终失败,并且您将无法删除事件监听器(不删除所有 事件监听器)。下面是平等检查中发生的事情的简单演示:

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

关于javascript - react 事件监听器, throttle 未被删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46102738/

相关文章:

javascript - 在 Greasemonkey 脚本中存储数据

javascript - 为什么 Escape 键在 Ace 编辑器中不起作用?

javascript - JS - 如何在不重新加载网页的情况下删除事件的事件监听器

javascript - 匹配打开和关闭标签

javascript - jQuery 电子表格/网格插件,可从 Excel 复制/粘贴到 Excel

reactjs - 为什么Ant设计中没有 `<Input>`的onchange

reactjs - Jest 测试失败 SyntaxError,意外的 token 导出

reactjs - 接口(interface)命名约定(接口(interface)名称与组件名称冲突)

javascript - 单击突出显示 div

javascript - 如何使用Vanilla JavaScript自动播放下一首歌