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

TanStack useInfiniteQuery问题:isFetching始终为true且data未定义

问题分析与解决方案

你的代码出现isFetching始终为true、data一直undefined的核心原因有两个:

1. 分页逻辑不匹配导致无限请求

useInfiniteQuery的getNextPageParam你写的是lastPage.nextCursor,但你的fetchUsers函数返回的对象里根本没有nextCursor字段——你返回的是{ resultUsers, resultPage }。这会导致getNextPageParam每次都返回undefined,而useInfiniteQuery会把undefined当成“还有下一页需要加载”,从而不断发起请求,陷入无限循环,自然data无法稳定,isFetching一直为true。

2. 类型断言掩盖了潜在错误

你用fetchUsers as any跳过了TypeScript的类型检查,这会让你无法提前发现返回类型和useInfiniteQuery泛型ResultUsers不匹配的问题,增加调试难度。


修复步骤

第一步:修正数据获取函数的返回值,补充分页判断

修改fetchUsers,让它返回明确的下一页标识,同时简化async/await写法:

interface Props {
  pageParam?: number;
}

// 定义返回类型,让TypeScript做类型检查
interface FetchUsersResponse {
  resultUsers: ResultUsers[]; // 确保ResultUsers是你定义的用户数组类型
  currentPage: number;
  nextPage?: number;
}

export async function fetchUsers({ pageParam = 1 }: Props): Promise<FetchUsersResponse> {
  const seed = 'horse';
  const apiLink = `https://XXXX.XX/api/?results=10&inc=email,picture,name,location&seed=${seed}&page=${pageParam}`;

  const response = await fetch(apiLink);
  if (!response.ok) throw new Error('Error when connecting to DB');
  
  const data = await response.json();
  
  const resultUsers = data.results.map(
    ({ email, picture, name, location }: Result) => ({
      id: email,
      picture: picture.thumbnail,
      firstName: name.first,
      lastName: name.last,
      country: location.country,
    })
  );

  const currentPage = Number(data.info.page);
  // 两种判断下一页的方式,选适合你API的:
  // 方式1:API返回总页数时用总页数判断
  const totalPages = Number(data.info.total_pages);
  const nextPage = currentPage < totalPages ? currentPage + 1 : undefined;
  
  // 方式2:API不返回总页数时,用结果数量判断(每页10条,少于10条则无下一页)
  // const nextPage = data.results.length === 10 ? currentPage + 1 : undefined;

  return { resultUsers, currentPage, nextPage };
}

第二步:修正useInfiniteQuery的配置

去掉as any断言,让TypeScript做类型检查,同时修正getNextPageParam的取值:

const { isLoading, isError, data, isFetching, refetch } = useInfiniteQuery<FetchUsersResponse>({
  queryKey: ['users'],
  queryFn: fetchUsers,
  initialPageParam: 1,
  getNextPageParam: (lastPage) => lastPage.nextPage, // 取正确的nextPage字段
});

第三步:正确观察状态变化

直接在组件顶层console.log会每次渲染都执行,可能看到的是初始状态。用useEffect监听状态变化,才能看到真实的更新:

import { useEffect } from 'react';

useEffect(() => {
  console.log('当前请求状态:', isFetching);
  console.log('获取到的数据:', data);
}, [isFetching, data]);

第四步:添加错误和加载状态的UI提示

快速排查是否有请求失败的情况:

if (isError) {
  return <div>数据加载失败,请稍后重试</div>;
}

if (isLoading) {
  return <div>加载中...</div>;
}

// 渲染数据的逻辑
return (
  <div>
    {data?.pages.map((page) => (
      <div key={page.currentPage}>
        {page.resultUsers.map(user => (
          <div key={user.id}>{user.firstName} {user.lastName}</div>
        ))}
      </div>
    ))}
  </div>
);

内容的提问来源于stack exchange,提问作者Juan Bautista De Angelis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 22:21:01