React 事件侦听器,但油门未被移除

use*_*977 3 javascript throttling addeventlistener reactjs

我的代码看起来像这样:

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

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

resize = () => this.forceUpdate();
Run Code Online (Sandbox Code Playgroud)

这工作正常。但后来我尝试添加一个油门以获得更好的性能

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

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

resize = () => this.forceUpdate();
Run Code Online (Sandbox Code Playgroud)

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

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.
Run Code Online (Sandbox Code Playgroud)

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

我尝试更新componentWillUnmount喜欢这样:

componentWillUnmount() {
    window.removeEventListener('resize', _.throttle(this.resize, 200));
}
Run Code Online (Sandbox Code Playgroud)

但这也不起作用。

有任何想法吗

Rob*_* M. 5

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

constructor(props) {
   ...
   this.throttledResize = _.throttle(this.resize, 200)
}

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

componentWillUnmount() {
    window.removeEventListener('resize', this.throttledResize);
}
Run Code Online (Sandbox Code Playgroud)

要详细说明为什么会这样,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;
   })
}
Run Code Online (Sandbox Code Playgroud)

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

constructor(props) {
   ...
   this.throttledResize = _.throttle(this.resize, 200)
}

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

componentWillUnmount() {
    window.removeEventListener('resize', this.throttledResize);
}
Run Code Online (Sandbox Code Playgroud)