我在反应中有更高阶的组件是这样的:
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,它们仍然会抛出错误,例如(当我滚动时):
InfiniteScrolling
警告:setState(…):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了setState()。这是无人值守。请检查未定义组件的代码。
即使确实删除了scroll组件卸载中的事件。没用
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); }
一切似乎都正常,没有任何问题。
我觉得它们是完全一样的,但是第二个可以正常工作,而第一个可以像前面提到的那样在控制台中抛出错误!
.bind总是会创建一个新函数,因此您需要执行以下操作,因此它会添加和删除相同的函数。
.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); }