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

React无限滚动组件问题:next自动多次调用API求助

React无限滚动中API被多次调用的问题排查与修复

问题核心原因

你的代码里有几个关键问题导致API被重复调用:

  1. useCallback依赖了responseData,每次数据更新都会重建fetchData函数,触发useEffect再次调用API
  2. 没有加载状态控制,滚动时会连续触发next回调
  3. hasMore始终设为true,不会停止后续请求
  4. 状态更新用了responseData.concat而非函数式写法,容易导致数据合并错误,同时加重依赖问题

修复步骤及代码修改

1. 添加加载状态,阻止并行请求

先新增一个状态来标记是否正在加载,避免同一时间发起多个API请求:

const [isLoading, setIsLoading] = useState(false);

2. 重构fetchData函数

修改fetchData,移除不必要的依赖,用函数式更新状态,同时添加加载状态控制:

const fetchData = useCallback(async () => {
    // 正在加载或已到最后一页时,直接返回
    if (isLoading || page > totalPage) return;
    
    setIsLoading(true);
    try {
        const response = await axios.get(`http://sampleURL/api/?page=${page}`);
        // 用函数式更新获取最新的state,避免依赖responseData
        setresponseData(prev => [...prev, ...response.data.users.data]);
        setTotalLength(response.data.users.total);
        setTotalPage(response.data.users.last_page);
        // 同样用函数式更新page
        setPage(prev => prev + 1);
    } catch (error) {
        console.error('加载数据失败:', error);
    } finally {
        setIsLoading(false);
    }
}, [page, totalPage, isLoading]);

3. 修正初始加载的useEffect

初始加载只需要触发一次,不需要依赖fetchData:

useEffect(() => {
    fetchData();
}, []);

4. 调整InfiniteScroll组件参数

  • dataLength改为已加载的数据长度(responseData.length),组件需要根据这个值判断何时触发下一页
  • hasMore根据当前页和总页数、加载状态动态判断:
<InfiniteScroll 
    dataLength={responseData.length}
    next={fetchData} 
    hasMore={page <= totalPage && !isLoading}
    scrollableTarget="scrollableDiv"
    loader={<div className="text-center py-4">加载中...</div>}
>
    <ResponseList responseData={responseData}/>
</InfiniteScroll>

关键修改说明

  • 加载状态isLoading:彻底避免滚动时连续触发next导致的重复API请求
  • 函数式状态更新:不再依赖responseData,防止useCallback频繁重建,同时保证状态更新的准确性
  • 正确的hasMore判断:当已加载到最后一页或者正在加载时,停止触发后续请求
  • dataLength修正:react-infinite-scroll-component的dataLength是用来计算滚动位置的,必须传入已加载的数据长度,而非总数据量

内容的提问来源于stack exchange,提问作者Dirty Rex

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 15:25:33