小编典典

在卸载React上删除事件监听器

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;
}

卸载通过包装的组件后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);
}

一切似乎都正常,没有任何问题。

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


阅读 919

收藏
2020-07-22

共1个答案

小编典典

.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);
    }
2020-07-22