无限查询与基于游标的分页
使用基于游标的分页和无限查询,在 tRPC 中实现可扩展的列表加载和无限滚动。
无限查询与基于游标的分页 是 CoddyKit 上的免费 tRPC End-to-End Type Safe APIs 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 tRPC End-to-End Type Safe APIs 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 tRPC End-to-End Type Safe APIs 课程共包含 4 节课。
本课时的部分内容尚未翻译,以英文显示。
Why Not Offset Pagination?
Offset pagination (page 1, 2, 3) breaks when data changes between requests and gets slow on large tables.
Cursor-based pagination uses a pointer to the last item, staying fast and stable.
The Cursor Concept
Each page returns items plus a nextCursor, the id or timestamp of where the next page should start.
Designing the Input
The procedure accepts a limit and an optional cursor.
const input = z.object({
limit: z.number().min(1).max(50).default(20),
cursor: z.string().nullish(),
});The Server Procedure
Fetch one extra item to know if there is a next page.
list: publicProcedure.input(input).query(async ({ input }) => {
const items = await db.getItems(input.limit + 1, input.cursor);
let nextCursor = undefined;
if (items.length > input.limit) {
const next = items.pop();
nextCursor = next.id;
}
return { items, nextCursor };
})Why Fetch limit + 1?
Requesting one more item than needed is a simple trick: if it exists, there is another page, and its id becomes the next cursor.
useInfiniteQuery on the Client
The React Query integration provides useInfiniteQuery tailored for this shape.
const q = trpc.item.list.useInfiniteQuery(
{ limit: 20 },
{ getNextPageParam: (last) => last.nextCursor }
);Rendering All Pages
Flatten the loaded pages into a single list for rendering.
const items = q.data?.pages.flatMap((p) => p.items) ?? [];Loading More
Trigger the next page when the user scrolls to the bottom.
if (q.hasNextPage) q.fetchNextPage();Stable Ordering
Cursor pagination needs a stable sort key, usually a unique, monotonic column like an auto id or created_at, so cursors stay valid.
Bidirectional Cursors
You can also return a previousCursor to scroll backward, useful for chat-style histories.
Showing a Loading State
Use the query flags to render spinners and disable the load-more button while a page is fetching.
if (q.isFetchingNextPage) showSpinner();Quick Check
Test your pagination knowledge.
Recap
You built scalable list loading:
- Cursor pagination beats offset for large, changing data
- Return items + nextCursor; fetch limit + 1 to detect more
- Use useInfiniteQuery and flatten pages on the client
This pattern powers smooth infinite scroll experiences.
常见问题解答
「无限查询与基于游标的分页」课时是免费的吗?
是的 — 「无限查询与基于游标的分页」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 tRPC End-to-End Type Safe APIs 课程的其余内容,请升级到 CoddyKit PRO。 tRPC End-to-End Type Safe APIs 课程共包含 4 节课。
「无限查询与基于游标的分页」这节课中我会学到什么?
使用基于游标的分页和无限查询,在 tRPC 中实现可扩展的列表加载和无限滚动。 你通过在浏览器中直接运行的动手代码来练习 tRPC End-to-End Type Safe APIs,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 tRPC End-to-End Type Safe APIs 需要有经验吗?
无需任何先前经验。CoddyKit 上的 tRPC End-to-End Type Safe APIs 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「无限查询与基于游标的分页」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 tRPC End-to-End Type Safe APIs 课中编写并运行代码吗?
能。每节 tRPC End-to-End Type Safe APIs 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 高效批量处理请求
- 实现乐观更新
- 使用 tRPC 上传文件
- 无限查询与基于游标的分页