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

如何使用useInfiniteQuery处理多查询与游标分页请求?

多接口无限游标加载的解决方案

针对你遇到的「需要同时处理多个带游标分页的接口,useInfiniteQuery不支持批量查询、useQueries无法适配无限加载」的问题,这里提供几个实用的解决思路:

方案一:用useQueries批量管理多个useInfiniteQuery实例

useQueries本身支持传入多个查询配置对象,每个对象可以完全按照useInfiniteQuery的参数来配置,包括getNextPageParam、fetchNextPage等无限加载相关选项,以此一次性创建多个独立的无限查询实例。

示例代码:

import { useQueries } from '@tanstack/react-query';

// 定义每个接口的查询配置
const queryConfigs = [
  {
    queryKey: ['projects'],
    queryFn: fetchProjects,
    getNextPageParam: (lastPage) => lastPage.nextCursor,
  },
  {
    queryKey: ['tasks'],
    queryFn: fetchTasks,
    getNextPageParam: (lastPage) => lastPage.nextCursor,
  },
  // 更多接口配置...
];

// 用useQueries批量创建无限查询
const queryResults = useQueries({
  queries: queryConfigs,
});

// 每个结果对应一个接口的无限查询状态
const [projectsQuery, tasksQuery] = queryResults;
// 调用单个接口的加载下一页方法
projectsQuery.fetchNextPage();

方案二:封装自定义Hook处理动态数量的无限查询

如果查询数量是动态的(比如从props传入),可以封装自定义Hook,内部通过useQueries动态生成查询配置,避免直接在组件map回调中调用Hook的问题。

示例代码:

import { useQueries } from '@tanstack/react-query';

function useMultiInfiniteQueries(queryConfigs) {
  return useQueries({
    queries: queryConfigs.map(config => ({
      ...config,
      queryKey: config.queryKey,
      getNextPageParam: config.getNextPageParam,
    })),
  });
}

// 在组件中使用
function MyComponent({ resources }) {
  // resources是动态接口列表,格式示例:[{key: 'projects', fetchFn: fetchProjects}, ...]
  const queryConfigs = resources.map(resource => ({
    queryKey: [resource.key],
    queryFn: resource.fetchFn,
    getNextPageParam: (lastPage) => lastPage.nextCursor,
  }));

  const queryResults = useMultiInfiniteQueries(queryConfigs);

  // 遍历结果处理每个接口的加载逻辑
  return (
    <div>
      {queryResults.map((result, index) => (
        <div key={resources[index].key}>
          {result.data?.pages.map(page => (
            <div key={page.nextCursor}>{/* 渲染数据 */}</div>
          ))}
          {result.hasNextPage && (
            <button onClick={() => result.fetchNextPage()} disabled={result.isFetchingNextPage}>
              加载更多
            </button>
          )}
        </div>
      ))}
    </div>
  );
}

方案三:拆分组件,每个接口对应独立子组件

如果动态查询数量较多,且每个接口的渲染逻辑独立,可以把单个无限查询的逻辑封装到子组件中,在父组件里通过map渲染子组件,这样每个子组件内部的useInfiniteQuery都在组件顶层调用,完全符合Hook规则。

示例代码:

// 子组件:单个接口的无限加载逻辑
function InfiniteResource({ resourceKey, fetchFn }) {
  const { data, hasNextPage, fetchNextPage, isFetchingNextPage } = useInfiniteQuery({
    queryKey: [resourceKey],
    queryFn: fetchFn,
    getNextPageParam: (lastPage) => lastPage.nextCursor,
  });

  return (
    <div>
      {data?.pages.map(page => (
        <div key={page.nextCursor}>{/* 渲染当前页数据 */}</div>
      ))}
      {hasNextPage && (
        <button onClick={() => fetchNextPage()} disabled={isFetchingNextPage}>
          加载更多
        </button>
      )}
    </div>
  );
}

// 父组件
function ParentComponent({ resources }) {
  return (
    <div>
      {resources.map(resource => (
        <InfiniteResource 
          key={resource.key} 
          resourceKey={resource.key} 
          fetchFn={resource.fetchFn} 
        />
      ))}
    </div>
  );
}

以上三种方案可根据业务场景选择:若需统一管理所有查询状态,优先选方案一或二;若每个接口的渲染和加载逻辑独立,方案三的组件拆分更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 21:25:13