在Unmount React上删除事件监听器

Ant*_*t's 31 javascript reactjs

我有更高阶的组件反应如下:

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

在卸载已经被包装的组件之后InfiniteScrolling,它们仍然会抛出错误(当我滚动时):

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

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

但是当我将代码改为这样:

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

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

componentWillUnmount() {
    window.removeEventListener('scroll', this.onScroll, false);
}
Run Code Online (Sandbox Code Playgroud)

一切似乎都很好,没有任何问题.

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

Yur*_*nko 88

你总是在创造新的功能

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

  • 天哪,这么简单的错误!Bind创建一个新功能。我的错! (3认同)

The*_*mid 7

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

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