React Infinite Scroller无限触发请求问题及修复方案咨询
修复react-infinite-scroller无限调用loadMore的问题
我来帮你排查这个无限触发fetchCompanies的问题,主要有几个核心原因和对应的修复方案:
问题根源分析
hasMore属性设置错误:你写的hasMore={true || false}是个永远为true的表达式,组件会一直认为还有更多数据需要加载,无限触发loadMore。- 未更新页码状态:每次调用
fetchCompanies时都用初始的page=0,请求成功后也没有递增页码,导致重复请求同一页数据,同时组件持续触发加载。 - 滚动容器配置缺失:当
useWindow={false}时,你需要给InfiniteScroll的父容器(.searchResults)设置固定高度和滚动属性,否则组件无法正确检测滚动位置,可能误判为已滚动到底部,不断触发加载。 - 无请求防抖/加载锁:没有设置加载状态锁,可能导致同一时间多次发起请求,加重无限调用的问题。
具体修复步骤
1. 更新组件状态
首先在constructor里添加必要的状态,用来控制是否还有更多数据、是否正在加载:
constructor(props) { super(props); this.state = { companies: [], page: 0, hasMore: true, // 控制是否还有更多数据 isLoading: false, // 防止重复请求的锁 }; }
2. 重构fetchCompanies函数
修改请求逻辑,添加加载锁、更新页码、判断是否还有更多数据:
fetchCompanies = () => { // 如果正在加载或者已经没有更多数据,直接返回 if (this.state.isLoading || !this.state.hasMore) return; this.setState({ isLoading: true }, () => { const currentPage = this.state.page; traineeship.getAll(currentPage).then(response => { // 检查返回数据是否有效且有内容 const newCompanies = response.data?._embedded?.companies || []; if (newCompanies.length > 0) { this.setState(prevState => ({ // 合并新数据到现有列表 companies: [...prevState.companies, ...newCompanies], // 页码递增 page: prevState.page + 1, isLoading: false })); } else { // 没有更多数据了,更新hasMore状态 this.setState({ hasMore: false, isLoading: false }); console.log('已加载全部实习岗位'); } }).catch(error => { console.error('加载实习岗位失败:', error); this.setState({ isLoading: false }); }); }); };
3. 修正InfiniteScroll组件属性
更新hasMore为动态状态,明确滚动父容器:
<InfiniteScroll pageStart={0} loadMore={this.fetchCompanies} // 只有当还有更多数据且不在加载中时,才允许触发加载 hasMore={this.state.hasMore && !this.state.isLoading} loader={<div className="loader" key={0}>Loading ...</div>} useWindow={false} // 明确指定滚动父容器(对应你的.searchResults元素) getScrollParent={() => document.querySelector('.searchResults')} > {/* 你的列表渲染逻辑保持不变 */} </InfiniteScroll>
4. 给滚动父容器添加样式
在你的traineeship.style.scss中给.searchResults添加滚动相关样式:
.searchResults { // 设置固定高度,根据你的页面布局调整数值 max-height: 70vh; // 开启垂直滚动 overflow-y: auto; // 防止滚动条遮挡内容 padding-right: 10px; }
额外提示
- 请根据你的API返回结构调整判断逻辑:如果API返回了总页数、是否有下一页等字段(比如
response.data.page.totalPages),可以用这些字段来更准确地判断hasMore,而不仅仅依赖返回数据的长度。 - 如果你的API有请求频率限制,建议添加防抖逻辑,避免短时间内多次触发请求。
内容的提问来源于stack exchange,提问作者Mizlul
相关产品推荐
相关产品推荐

