/
githubmirror
/
trpc
Обзор
Документация
Войти
/
githubmirror
/
trpc
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
www/docs/client/tanstack-react-query/setup.mdx
297 строк
9 KB
Nick Lucas
feat: Tanstack Intent Skills (#7252)
21 мар 2026, 02:18
Не верифицирован
21 мар 2026, 02:18
e39a654
Код
Авторство
О чём код?
--- id: setup title: TanStack React Query sidebar_label: Setup description: TanStack React Query setup slug: /client/tanstack-react-query/setup --- Compared to our [classic React Query Integration](/docs/client/react) this client is simpler and more TanStack Query-native, providing factories for common TanStack React Query interfaces like QueryKeys, QueryOptions, and MutationOptions. We think it's the future and recommend using this over the classic client, <a href="/blog/introducing-tanstack-react-query-client">read the announcement post</a> for more information about this change. :::tip You can try this integration out on the homepage of tRPC.io: [https://trpc.io/?try=minimal-react#try-it-out](/?try=minimal-react#try-it-out) ::: <details> <summary>❓ Do I have to use an integration?</summary> No! The integration is fully optional. You can use `@tanstack/react-query` using just a [vanilla tRPC client](/docs/client/vanilla), although then you'll have to manually manage query keys and do not get the same level of DX as when using the integration package. ```ts twoslash title='utils/trpc.ts' // @filename: server/router.ts import { initTRPC } from '@trpc/server'; const t = initTRPC.create(); const appRouter = t.router({ post: t.router({ list: t.procedure.query(() => [{ id: '1', title: 'Hello' }]), }), }); export type AppRouter = typeof appRouter; // @filename: utils/trpc.ts // ---cut--- import { createTRPCClient, httpBatchLink } from '@trpc/client'; import type { AppRouter } from '../server/router'; export const trpc = createTRPCClient<AppRouter>({ links: [httpBatchLink({ url: 'YOUR_API_URL' })], }); ``` ```tsx twoslash title='components/PostList.tsx' // @filename: server/router.ts import { initTRPC } from '@trpc/server'; const t = initTRPC.create(); const appRouter = t.router({ post: t.router({ list: t.procedure.query(() => [{ id: '1', title: 'Hello' }]), }), }); export type AppRouter = typeof appRouter; // @filename: utils/trpc.ts import { createTRPCClient, httpBatchLink } from '@trpc/client'; import type { AppRouter } from '../server/router'; export const trpc = createTRPCClient<AppRouter>({ links: [httpBatchLink({ url: 'YOUR_API_URL' })], }); // @filename: component.tsx // ---cut--- import { useQuery } from '@tanstack/react-query'; import { trpc } from './utils/trpc'; function PostList() { const { data } = useQuery({ queryKey: ['posts'] as const, queryFn: () => trpc.post.list.query(), }); data; // Post[] // ... } ``` </details> ## Setup ### 1. Install dependencies The following dependencies should be installed import { InstallSnippet } from '@site/src/components/InstallSnippet'; import TabItem from '@theme/TabItem'; import Tabs from '@theme/Tabs'; <InstallSnippet pkgs="@trpc/server @trpc/client @trpc/tanstack-react-query @tanstack/react-query" /> :::tip AI Agents If you use an AI coding agent, install tRPC skills for better code generation: ```bash npx @tanstack/intent@latest install ``` ::: ### 2. Import your `AppRouter` ```twoslash include router // @filename: server/router.ts // ---cut--- import { initTRPC } from '@trpc/server'; import { z } from "zod"; const t = initTRPC.create(); const appRouter = t.router({ getUser: t.procedure.input(z.object({ id: z.string() })).query(() => ({ name: 'foo' })), createUser: t.procedure.input(z.object({ name: z.string() })).mutation(() => 'bar'), }); export type AppRouter = typeof appRouter; ``` ```twoslash include utils-a // @filename: utils/trpc.ts // ---cut--- import { createTRPCContext } from '@trpc/tanstack-react-query'; import type { AppRouter } from '../server/router'; export const { TRPCProvider, useTRPC, useTRPCClient } = createTRPCContext<AppRouter>(); ``` import ImportAppRouter from '../../partials/_import-approuter.mdx'; <ImportAppRouter /> ### 3a. Set up the tRPC context provider In cases where you rely on React context, such as when using server-side rendering in full-stack frameworks like Next.js, it's important to create a new QueryClient for each request so that your users don't end up sharing the same cache, you can use the `createTRPCContext` to create a set of type-safe context providers and consumers from your `AppRouter` type signature. ```tsx title='utils/trpc.ts' twoslash // @include: router // @include: utils-a ``` Then, create a tRPC client, and wrap your application in the `TRPCProvider`, as below. You will also need to set up and connect React Query, which [they document in more depth](https://tanstack.com/query/latest/docs/framework/react/quick-start). :::tip If you already use React Query in your application, you **should** re-use the `QueryClient` and `QueryClientProvider` you already have. You can read more about the QueryClient initialization in the [React Query docs](https://tanstack.com/query/latest/docs/framework/react/guides/advanced-ssr#initial-setup). ::: ```tsx twoslash title='components/App.tsx' // @jsx: react-jsx // @include: router // @include: utils-a // @filename: components/App.tsx // ---cut--- import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { createTRPCClient, httpBatchLink } from '@trpc/client'; import { useState } from 'react'; import type { AppRouter } from '../server/router'; import { TRPCProvider } from '../utils/trpc'; function makeQueryClient() { return new QueryClient({ defaultOptions: { queries: { // With SSR, we usually want to set some default staleTime // above 0 to avoid refetching immediately on the client staleTime: 60 * 1000, }, }, }); } let browserQueryClient: QueryClient | undefined = undefined; function getQueryClient() { if (typeof window === 'undefined') { // Server: always make a new query client return makeQueryClient(); } else { // Browser: make a new query client if we don't already have one // This is very important, so we don't re-make a new client if React // suspends during the initial render. This may not be needed if we // have a suspense boundary BELOW the creation of the query client if (!browserQueryClient) browserQueryClient = makeQueryClient(); return browserQueryClient; } } export function App() { const queryClient = getQueryClient(); const [trpcClient] = useState(() => createTRPCClient<AppRouter>({ links: [ httpBatchLink({ url: 'http://localhost:2022', }), ], }), ); return ( <QueryClientProvider client={queryClient}> <TRPCProvider trpcClient={trpcClient} queryClient={queryClient}> {null /* Your app here */} </TRPCProvider> </QueryClientProvider> ); } ``` ### 3b. Set up with Query/Mutation Key Prefixing enabled If you want to prefix all queries and mutations with a specific key, see [Query Key Prefixing](./usage.mdx#keyPrefix) for setup and usage examples. ### 3c. Set up without React context When building an SPA using only client-side rendering with something like Vite, you can create the `QueryClient` and tRPC client outside of React context as singletons. ```ts twoslash title='utils/trpc.ts' // @include: router // @filename: utils/trpc.ts // ---cut--- import { QueryClient } from '@tanstack/react-query'; import { createTRPCClient, httpBatchLink } from '@trpc/client'; import { createTRPCOptionsProxy } from '@trpc/tanstack-react-query'; import type { AppRouter } from '../server/router'; export const queryClient = new QueryClient(); const trpcClient = createTRPCClient<AppRouter>({ links: [httpBatchLink({ url: 'http://localhost:2022' })], }); export const trpc = createTRPCOptionsProxy<AppRouter>({ client: trpcClient, queryClient, }); ``` ```tsx twoslash title='components/App.tsx' // @include: router // @filename: utils/trpc.ts import { QueryClient } from '@tanstack/react-query'; import { createTRPCClient, httpBatchLink } from '@trpc/client'; import { createTRPCOptionsProxy } from '@trpc/tanstack-react-query'; import type { AppRouter } from '../server/router'; export const queryClient = new QueryClient(); const trpcClient = createTRPCClient<AppRouter>({ links: [httpBatchLink({ url: 'http://localhost:2022' })], }); export const trpc = createTRPCOptionsProxy<AppRouter>({ client: trpcClient, queryClient, }); // @filename: components/App.tsx import React from 'react'; // ---cut--- import { QueryClientProvider } from '@tanstack/react-query'; import { queryClient } from '../utils/trpc'; export function App() { return ( <QueryClientProvider client={queryClient}> {/* Your app here */} </QueryClientProvider> ); } ``` ### 4. Fetch data You can now use the tRPC React Query integration to call queries and mutations on your API. ```tsx twoslash title='components/user-list.tsx' // @jsx: react-jsx // @include: router // @include: utils-a // @filename: components/user-list.tsx // ---cut--- import { useMutation, useQuery } from '@tanstack/react-query'; import { useTRPC } from '../utils/trpc'; export default function UserList() { const trpc = useTRPC(); // use `import { trpc } from './utils/trpc'` if you're using the singleton pattern const userQuery = useQuery(trpc.getUser.queryOptions({ id: 'id_bilbo' })); const userCreator = useMutation(trpc.createUser.mutationOptions()); return ( <div> <p>{userQuery.data?.name}</p> <button onClick={() => userCreator.mutate({ name: 'Frodo' })}> Create Frodo </button> </div> ); } ```