useInfiniteQuery
info
- 您的过程需要接受任何类型(
string
、number
等)的cursor
输入才能公开此钩子。 - 有关无限查询的更多详细信息,请阅读 react-query 文档
- 在此示例中,我们使用的是 Prisma - 请参阅其关于 基于游标的分页 的文档
示例过程
server/routers/_app.tstsx
import { initTRPC } from '@trpc/server';import { z } from 'zod';import { Context } from './[trpc]';export const t = initTRPC.create();export const appRouter = t.router({infinitePosts: t.procedure.input(z.object({limit: z.number().min(1).max(100).nullish(),cursor: z.number().nullish(), // <-- "cursor" needs to exist, but can be any typedirection: z.enum(['forward', 'backward']), // optional, useful for bi-directional query}),).query(async (opts) => {const { input } = opts;const limit = input.limit ?? 50;const { cursor } = input;const items = await prisma.post.findMany({take: limit + 1, // get an extra item at the end which we'll use as next cursorwhere: {title: {contains: 'Prisma' /* Optional filter */,},},cursor: cursor ? { myCursor: cursor } : undefined,orderBy: {myCursor: 'asc',},});let nextCursor: typeof cursor | undefined = undefined;if (items.length > limit) {const nextItem = items.pop();nextCursor = nextItem!.myCursor;}return {items,nextCursor,};}),});
server/routers/_app.tstsx
import { initTRPC } from '@trpc/server';import { z } from 'zod';import { Context } from './[trpc]';export const t = initTRPC.create();export const appRouter = t.router({infinitePosts: t.procedure.input(z.object({limit: z.number().min(1).max(100).nullish(),cursor: z.number().nullish(), // <-- "cursor" needs to exist, but can be any typedirection: z.enum(['forward', 'backward']), // optional, useful for bi-directional query}),).query(async (opts) => {const { input } = opts;const limit = input.limit ?? 50;const { cursor } = input;const items = await prisma.post.findMany({take: limit + 1, // get an extra item at the end which we'll use as next cursorwhere: {title: {contains: 'Prisma' /* Optional filter */,},},cursor: cursor ? { myCursor: cursor } : undefined,orderBy: {myCursor: 'asc',},});let nextCursor: typeof cursor | undefined = undefined;if (items.length > limit) {const nextItem = items.pop();nextCursor = nextItem!.myCursor;}return {items,nextCursor,};}),});
示例 React 组件
components/MyComponent.tsxtsx
import { trpc } from '../utils/trpc';export function MyComponent() {const myQuery = trpc.infinitePosts.useInfiniteQuery({limit: 10,},{getNextPageParam: (lastPage) => lastPage.nextCursor,// initialCursor: 1, // <-- optional you can pass an initialCursor},);// [...]}
components/MyComponent.tsxtsx
import { trpc } from '../utils/trpc';export function MyComponent() {const myQuery = trpc.infinitePosts.useInfiniteQuery({limit: 10,},{getNextPageParam: (lastPage) => lastPage.nextCursor,// initialCursor: 1, // <-- optional you can pass an initialCursor},);// [...]}
助手
getInfiniteData()
此助手从现有无限查询中获取当前缓存的数据
components/MyComponent.tsxtsx
import { trpc } from '../utils/trpc';export function MyComponent() {const utils = trpc.useUtils();const myMutation = trpc.infinitePosts.add.useMutation({async onMutate(opts) {await utils.infinitePosts.cancel();const allPosts = utils.infinitePosts.getInfiniteData({ limit: 10 });// [...]},});}
components/MyComponent.tsxtsx
import { trpc } from '../utils/trpc';export function MyComponent() {const utils = trpc.useUtils();const myMutation = trpc.infinitePosts.add.useMutation({async onMutate(opts) {await utils.infinitePosts.cancel();const allPosts = utils.infinitePosts.getInfiniteData({ limit: 10 });// [...]},});}
setInfiniteData()
此助手允许您更新查询的缓存数据
components/MyComponent.tsxtsx
import { trpc } from '../utils/trpc';export function MyComponent() {const utils = trpc.useUtils();const myMutation = trpc.infinitePosts.delete.useMutation({async onMutate(opts) {await utils.infinitePosts.cancel();utils.infinitePosts.setInfiniteData({ limit: 10 }, (data) => {if (!data) {return {pages: [],pageParams: [],};}return {...data,pages: data.pages.map((page) => ({...page,items: page.items.filter((item) => item.status === 'published'),})),};});},});// [...]}
components/MyComponent.tsxtsx
import { trpc } from '../utils/trpc';export function MyComponent() {const utils = trpc.useUtils();const myMutation = trpc.infinitePosts.delete.useMutation({async onMutate(opts) {await utils.infinitePosts.cancel();utils.infinitePosts.setInfiniteData({ limit: 10 }, (data) => {if (!data) {return {pages: [],pageParams: [],};}return {...data,pages: data.pages.map((page) => ({...page,items: page.items.filter((item) => item.status === 'published'),})),};});},});// [...]}