Javascript 在卸载 React 时删除事件侦听器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38564080/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 21:36:24  来源:igfitidea点击:

Remove Event Listener On Unmount React

javascriptreactjs

提问by Ant's

I had higher order component in react like this:

我在反应中具有更高阶的组件,如下所示:

export default function (InnerComponent) {
    class InfiniteScrolling extends React.Component {

        constructor(props){
            super(props);
        }

        componentDidMount() {
            window.addEventListener('scroll', this.onScroll.bind(this), false);
        }

        componentWillUnmount() {
            window.removeEventListener('scroll', this.onScroll.bind(this), false);
        }

        onScroll() {
            if ((window.innerHeight + window.scrollY) >= (document.body.offsetHeight - 50)) {
                const { scrollFunc } = this.props;
                scrollFunc();
            }
        }

        render() {
            return <InnerComponent {...this.props} />;
        }
    }

    InfiniteScrolling.propTypes = {
        scrollFunc: PropTypes.func.isRequired
    };

    return InfiniteScrolling;
}

After unmounting the component which are been wrapped via InfiniteScrolling, they where still throwing the error like (when I did scrolling):

卸载通过 包装的组件后InfiniteScrolling,它们仍然抛出错误,例如(当我滚动时):

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

警告:setState(...):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了 setState()。这是一个无操作。请检查未定义组件的代码。

Even though I did remove the scrollevent on my component unmount. It didn't work.

即使我确实删除了scroll组件卸载上的事件。它没有用。

But when I changed the code to like this:

但是当我把代码改成这样时:

constructor(props){
    super(props);
    this.onScroll = this.onScroll.bind(this);
}

componentDidMount() {
    window.addEventListener('scroll', this.onScroll, false);
}

componentWillUnmount() {
    window.removeEventListener('scroll', this.onScroll, false);
}

everything seems to be working fine, without any issues.

一切似乎都运行良好,没有任何问题。

I feel they are exactly the same thing, but the second one works fine while the first one was throwing up the error in the console as mentioned before!

我觉得它们完全一样,但是第二个工作正常,而第一个在控制台中抛出了前面提到的错误!

回答by Yury Tarabanko

.bindalways creates a new function so you need to do like below, so it adds and removes the same function.

.bind总是创建一个新函数,所以你需要像下面那样做,所以它添加和删除了相同的函数。

    constructor(props){
        super(props);
        this.onScroll = this.onScroll.bind(this); //bind function once
    }

    componentDidMount() {
        window.addEventListener('scroll', this.onScroll, false);
    }

    componentWillUnmount() {
        // you need to unbind the same listener that was binded.
        window.removeEventListener('scroll', this.onScroll, false);
    }

回答by The pyramid

      componentDidMount() {
            window.addEventListener('scroll', this.onScroll, false);
        }

        componentWillUnmount() {
            window.removeEventListener('scroll', this.onScroll, false);
        }
        // use arrow function instead
        onScroll = () => { 
            if ((window.innerHeight + window.scrollY) >= (document.body.offsetHeight - 50)) {
                const { scrollFunc } = this.props;
                scrollFunc();
            }
        }

or you can use Arrow functions , to solve .bind(this) problems it worked form just fine.

或者你可以使用箭头函数来解决 .bind(this) 问题,它工作得很好。

回答by gakeko betsi

A working version for my project with Arrow Function and no-bind:

带有箭头函数和无绑定的我的项目的工作版本:

componentDidMount = () => {
  window.addEventListener("wheel", this.onScroll, false);
};

componentWillUnmount() {
  window.removeEventListener("wheel", this.onScroll, false);
}

onScroll = (e) => {
  const item = this.refs.myElement;
  if (e.deltaY > 0) item.scrollLeft += 200;
  else item.scrollLeft -= 200;
};