跳转到内容

Infinite Query:无限加载与分页窗口

普通 Query 管理的是单个 TData;Infinite Query 管理的是按页累积的数据:

type InfiniteData<TData, TPageParam> = {
pages: readonly TData[];
pageParams: readonly TPageParam[];
};

适用场景:无限滚动、加载更多、聊天记录双向翻页。

import { useInfiniteQuery } from '@iostore/react';
type Page = { items: { id: number; title: string }[]; nextCursor: number | null };
export function Feed() {
const feed = useInfiniteQuery<Page, Error, number>({
key: ['feed'],
initialPageParam: 0,
queryFn: async ({ signal, pageParam }) => {
const res = await fetch(`/api/feed?cursor=${pageParam}`, { signal });
return (await res.json()) as Page;
},
getNextPageParam: (lastPage) => lastPage.nextCursor,
});
const rows = feed.data?.pages.flatMap((page) => page.items) ?? [];
return (
<>
{rows.map((item) => (
<div key={item.id}>{item.title}</div>
))}
<button disabled={!feed.hasNextPage || feed.isFetchingNextPage} onClick={() => void feed.fetchNextPage()}>
{feed.isFetchingNextPage ? '加载中...' : '加载更多'}
</button>
</>
);
}
参数是否必填说明
initialPageParam第一页参数
queryFn({ signal, pageParam })相比普通 Query,新增 pageParam
getNextPageParam(lastPage, allPages, lastPageParam, allPageParams)返回 null/undefined 表示无下一页
getPreviousPageParam(...)启用向前加载(聊天记录)
maxPages限制缓存页数,超出后按方向裁剪
  • 数据字段:data.pagesdata.pageParams
  • 方向字段:fetchDirectionforward / backward / null
  • 派生字段:hasNextPagehasPreviousPageisFetchingNextPageisFetchingPreviousPage

常用方法:

  • fetchNextPage() / fetchPreviousPage()
  • refetch()(Hook 层映射到 refetchAllPages()
  • prefetch()
  • invalidate(refetch?)
  • cancel()
  • 页码型列表:优先看 分页、预取与取消
  • 无限滚动:优先使用 Infinite Query,减少手写聚合逻辑