You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React Query无限滚动分页滚动至最后一页后重复请求第一页的问题排查

React Query无限滚动分页滚动至最后一页后重复请求第一页的问题排查

看起来你遇到的是无限滚动到最后一页后,React Query反复请求第0页的问题,咱们一步步来拆解排查:

首先核查getNextPageParam的分页逻辑

你的分页判断基于Spring Boot返回的0起始pagetotalPages,先确认这个核心逻辑有没有漏洞:

getNextPageParam: (lastPage) => {
    const currentPage = lastPage.metadata.paging?.page as number;
    const totalPages = lastPage.metadata.paging?.totalPages as number;
    return currentPage < totalPages - 1
        ? currentPage + 1
        : undefined;
},

这个逻辑本身是成立的:比如总页数为3(页面索引0、1、2),当currentPage走到2时,2 < 3-1不成立,返回undefined,此时hasNextPage会自动变为false,理论上不会再触发下一页请求。

潜在风险点

  • 有没有可能后端返回的metadata.paging偶尔缺失?如果lastPage.metadata.pagingundefinedcurrentPagetotalPages会被转成NaNNaN < NaN结果为false,返回undefined,但如果后端返回状态不稳定,可能导致hasNextPage状态混乱。
  • 确认后端totalPages的准确性:比如当数据刚好是整页(10条数据,每页10条),totalPages应该返回1,此时currentPage=00 < 1-1不成立,正确返回undefined

接着检查FlatList的触发逻辑

你的onEndReached加了distanceFromEnd判断,但仍可能存在频繁触发的情况:

onEndReached={({ distanceFromEnd }) => {
  if (distanceFromEnd < 0) return;
  loadMore()
}}

潜在问题点

  • onEndReachedThreshold={0.1}意味着滚动到距离底部10%位置就会触发,如果第一页数据不足一屏,会反复触发onEndReached。虽然loadMore里有hasNextPage判断,但如果状态更新不及时,可能出现异常请求。
  • 你的keyExtractor用了索引:keyExtractor={(_, index) => index.toString()},新数据加载后列表项索引会变化,可能导致组件不必要的重渲染,间接触发onEndReached。建议换成数据的唯一ID,比如keyExtractor={(item) => item.id.toString()}

最后排查是否有意外触发refetch的情况

如果不是fetchNextPage发起的请求,而是整个查询被重新触发(比如请求第0页),可能是以下原因:

  • useInfiniteQuery默认开启refetchOnWindowFocus,应用从后台切回前台时会自动重新请求。如果你的场景频繁出现这种情况,可以关闭该配置:
    return useInfiniteQuery<ApiResponseListNote, AxiosError, Response>({
      // ...其他配置
      refetchOnWindowFocus: false,
    });
    
  • 检查queryKey的稳定性:你的queryKey['userNotes', {kindeId}],如果kindeId在滚动过程中意外变化,会触发整个查询重新执行,请求第0页。可以打印kindeId确认它是否保持稳定。

快速验证步骤

  1. getNextPageParam中添加日志,确认分页参数计算是否正确:
    getNextPageParam: (lastPage) => {
        const currentPage = lastPage.metadata.paging?.page as number;
        const totalPages = lastPage.metadata.paging?.totalPages as number;
        console.log('当前页码:', currentPage, '总页数:', totalPages);
        return currentPage < totalPages - 1
            ? currentPage + 1
            : undefined;
    },
    
  2. loadMore中添加日志,确认只有hasNextPagetrue时才会发起请求:
    const loadMore = () => {
        console.log('触发加载更多,hasNextPage:', hasNextPage);
        if (hasNextPage) {
           fetchNextPage();
        }
    };
    
  3. 如果使用了React Query DevTools,可以直接观察请求触发原因,是fetchNextPage还是refetch导致的第0页请求。

按照这些步骤排查,应该能定位到问题根源。

备注:内容来源于stack exchange,提问作者asfarasiknow

火山引擎 最新活动