使用TanStack Query v5的useInfiniteQuery结合JSON:API重复加载首页问题
问题分析与解决
你的核心问题在于**useInfiniteQuery的queryFn没有使用pageParam参数**,每次请求都硬编码了第一页的URL,所以哪怕getNextPageParam返回了正确的下一页链接,实际请求时还是会重复调用初始URL,导致加载重复数据。
具体修正步骤
1. 修改useMyInfiniteQuery的queryFn,传入pageParam
queryFn需要接收TanStack Query提供的上下文参数,其中包含pageParam(也就是你在getNextPageParam里返回的下一页链接)。调整后的代码如下:
function useMyInfiniteQuery() { const initialUrl = 'https://example.com/jsonapi/private?&filter[x.id][value]=2dd6dbda-4e17-45ff-b766-8c1047825d9c&sort=-c'; return useInfiniteQuery({ queryKey: ['myInfiniteQuery'], // 修正原代码中缺失字段名的错误 queryFn: async ({ pageParam = initialUrl }) => getQueryMyStuff(pageParam), // 直接使用pageParam作为请求URL initialPageParam: initialUrl, // 初始pageParam设为第一页的URL getNextPageParam: (lastPage) => { if (lastPage?.links?.next?.href) { return lastPage.links.next.href; } return undefined; }, }); }
2. 修复getQueryMyStuff的返回值类型问题
你的getQueryMyStuff声明返回Promise<ResponseProcessedMemoriesWithPager>,但最后返回了false,这会导致类型不匹配。应该返回一个符合类型定义的空结构:
const getQueryMyStuff = async ( query: string, ): Promise<ResponseProcessedMemoriesWithPager> => { const response = await fetchAuth(query); if (isResponseDataNonEmptyArray(response)) { const { data } = response; if (isDataExpectedObject(data)) { const returnData: MyObject[] = data.map(element => new MyObject(element)); return { data: returnData, links: response.links, }; } } // 返回符合类型的空结构,而非false return { data: [], links: {}, }; };
修正逻辑说明
initialPageParam设为第一页的URL,第一次请求时queryFn会用这个值调用getQueryMyStuff。- 点击“Load more”时,TanStack Query会把
getNextPageParam返回的下一页链接作为pageParam传给queryFn,此时getQueryMyStuff就会请求正确的下一页数据。 - 修正返回值类型避免潜在的渲染错误,确保
lastPage始终是有效的对象,不会因为返回false导致getNextPageParam读取属性时出错。
内容的提问来源于stack exchange,提问作者Patrick Kenny
相关产品推荐
相关产品推荐

