如何阻止InfiniteScroll滚动到顶部时调用next函数
问题描述
我在项目中使用了infinite-scroll组件,目前遇到的问题是:当滚动到窗口顶部时,next函数会被调用并发起请求获取新数据,但该函数仅应在滚动到列表底部时触发。
组件使用代码
<InfiniteScroll dataLength={notificationList.length} next={this.fetchMoreData} hasMore={this.state.hasMore} loader={<div className={'text-center'}>{Utils.i18n('loadingList', true)}</div>}> {notificationList.length > 0 && notificationList.map((item, index) => { return ( <div key={item.id} name={"scroll-to-element-" + item.id} className={"notification-wrap"}> <div className={"row"}> <div className={"col-auto"}> <h4 className={"title"}> {item.title} </h4> </div> <div className={"col-auto mr-auto"}> <span className={"date"}> {item.createdAt} </span> </div> </div> <div className={"description"}> <blockquote> {item.description} </blockquote> </div> </div> ); })} </InfiniteScroll> {notificationList.length === 0 && !notificationListLoading&& <div className={"text-center my-4"}> {Utils.i18n('noData', true)} </div> }
fetchMoreData函数代码
fetchMoreData = () => { if (this.props.notificationSettingReducer.notificationsList) { if (this.state.page < this.props.notificationSettingReducer.notificationsList.totalPages) { this.setState({ page: this.state.page + 1 }, () => { this.getNotification(); }); } if (this.state.page === this.props.notificationSettingReducer.notificationsList.totalPages) { this.setState({hasMore: false}); } } };
解决方案
可以通过以下几种方法阻止顶部触发next函数:
- 方法一:在
fetchMoreData中增加滚动位置判断
在函数开头添加滚动位置校验,当滚动到顶部时直接返回,不执行后续请求逻辑:
fetchMoreData = () => { // 滚动到顶部时直接终止函数执行 if (window.scrollY === 0) return; if (this.props.notificationSettingReducer.notificationsList) { if (this.state.page < this.props.notificationSettingReducer.notificationsList.totalPages) { this.setState({ page: this.state.page + 1 }, () => { this.getNotification(); }); } if (this.state.page === this.props.notificationSettingReducer.notificationsList.totalPages) { this.setState({hasMore: false}); } } };
- 方法二:指定滚动容器(非窗口滚动场景)
如果你的列表是在固定高度的容器内滚动,而非整个窗口,给InfiniteScroll添加scrollableTarget属性,指定容器ID,让组件只监听容器内的滚动事件:
// 先给列表外层容器添加ID和滚动样式 <div id="notification-container" style={{ height: '80vh', overflow: 'auto' }}> <InfiniteScroll dataLength={notificationList.length} next={this.fetchMoreData} hasMore={this.state.hasMore} loader={<div className={'text-center'}>{Utils.i18n('loadingList', true)}</div>} scrollableTarget="notification-container" // 指定滚动容器 > {/* 原有列表内容 */} </InfiniteScroll> </div>
- 方法三:关闭反向滚动配置
部分infinite-scroll库支持反向滚动(顶部加载更多),如果开启了该配置会导致顶部触发请求,需明确关闭:
<InfiniteScroll // 其他原有属性 reverse={false} // 关闭反向滚动 > {/* 原有列表内容 */} </InfiniteScroll>
内容的提问来源于stack exchange,提问作者Majid M.
相关产品推荐
相关产品推荐

