You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Infinite Scroller无限触发请求问题及修复方案咨询

修复react-infinite-scroller无限调用loadMore的问题

我来帮你排查这个无限触发fetchCompanies的问题,主要有几个核心原因和对应的修复方案:

问题根源分析

  1. hasMore属性设置错误:你写的hasMore={true || false}是个永远为true的表达式,组件会一直认为还有更多数据需要加载,无限触发loadMore。
  2. 未更新页码状态:每次调用fetchCompanies时都用初始的page=0,请求成功后也没有递增页码,导致重复请求同一页数据,同时组件持续触发加载。
  3. 滚动容器配置缺失:当useWindow={false}时,你需要给InfiniteScroll的父容器(.searchResults)设置固定高度和滚动属性,否则组件无法正确检测滚动位置,可能误判为已滚动到底部,不断触发加载。
  4. 无请求防抖/加载锁:没有设置加载状态锁,可能导致同一时间多次发起请求,加重无限调用的问题。

具体修复步骤

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:50:48