useInfiniteQuery
info
- Your procedure needs to accept a 
cursorinput ofanytype - For more details on infinite queries read the react-query docs
 - In this example we're using Prisma - see their docs on cursor-based pagination
 
Example Procedure​
server/routers/_app.ts
import { initTRPC } from '@trpc/server'
import { Context } from './[trpc]';
export const t = initTRPC()()
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 type
    })),
    .query(({ input }) => {
      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 cursor
        where: {
          title: {
            contains: 'Prisma' /* Optional filter */,
          },
        },
        cursor: cursor ? { myCursor: cursor } : undefined,
        orderBy: {
          myCursor: 'asc',
        },
      })
      let nextCursor: typeof cursor | null = null;
      if (items.length > limit) {
        const nextItem = items.pop()
        nextCursor = nextItem!.myCursor;
      }
      return {
        items,
        nextCursor,
      };
    })
})
Example React Component​
components/MyComponent.tsx
import { trpc } from '../utils/trpc';
export function MyComponent() {
  const myQuery = trpc.proxy.infinitePosts.useInfiniteQuery(
    {
      limit: 10,
    },
    {
      getNextPageParam: (lastPage) => lastPage.nextCursor,
    },
  );
  // [...]
}
Helpers​
getInfiniteQueryData()​
This helper gets the currently cached data from an existing infinite query
components/MyComponent.tsx
import { trpc } from '../utils/trpc';
export function MyComponent() {
  const utils = trpc.useContext();
  const myMutation = trpc.proxy.infinitePosts.add.useMutation({
    onMutate({ post }) {
      await utils.cancelQuery(['infinitePosts']);
      const allPosts = utils.getInfiniteQueryData(['infinitePosts', { limit: 10 }]);
      // [...]
    }
  })
}
setInfiniteQueryData()​
This helper allows you to update a queries cached data
components/MyComponent.tsx
import { trpc } from '../utils/trpc';
export function MyComponent() {
  const utils = trpc.useContext();
  const myMutation = trpc.proxy.infinitePosts.delete.useMutation({
    onMutate({ post }) {
      await utils.cancelQuery(['infinitePosts']);
      utils.setInfiniteQueryData(['infinitePosts', { limit: 10 }], (data) => {
        if (!data) {
          return {
            pages: [],
            pageParams: []
          }
        }
        return {
          ...data,
          pages: data.pages.map((page) => {
            ...page,
            items: page.items.filter((item) => item.status === 'published')
          })
        }
      });
    }
  });
  // [...]
}