Saltar al contenido principal
Versión: 11.x

TanStack React Query

Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

Compared to our classic React Query Integration 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, read the announcement post for more information about this change.

consejo

Puedes probar esta integración en la página principal de tRPC.io: https://trpc.io/?try=minimal-react#try-it-out

❓ Do I have to use an integration?

No! The integration is fully optional. You can use @tanstack/react-query using just a vanilla tRPC client, 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.

utils/trpc.ts
ts
export const trpc = createTRPCClient<AppRouter>({
links: [httpBatchLink({ url: 'YOUR_API_URL' })],
});
utils/trpc.ts
ts
export const trpc = createTRPCClient<AppRouter>({
links: [httpBatchLink({ url: 'YOUR_API_URL' })],
});
components/PostList.tsx
tsx
function PostList() {
const { data } = useQuery({
queryKey: ['posts'],
queryFn: () => trpc.post.list.query(),
});
data; // Post[]
// ...
}
components/PostList.tsx
tsx
function PostList() {
const { data } = useQuery({
queryKey: ['posts'],
queryFn: () => trpc.post.list.query(),
});
data; // Post[]
// ...
}

Configuración

1. Instalar dependencias

Se deben instalar las siguientes dependencias:

npm install @trpc/server @trpc/client @trpc/tanstack-react-query @tanstack/react-query

2. Importa tu AppRouter

Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

Importa el tipo AppRouter en la aplicación cliente. Este tipo contiene la estructura completa de tu API.

utils/trpc.ts
ts
import type { AppRouter } from '../server/router';
utils/trpc.ts
ts
import type { AppRouter } from '../server/router';
consejo

Al usar import type aseguras que la referencia será eliminada durante la compilación, evitando importar código del servidor en el cliente accidentalmente. Para más información, consulta la documentación de TypeScript.

3a. Configurar el proveedor de contexto de tRPC

En casos donde dependas del contexto de React, como cuando usas renderizado del lado del servidor en frameworks full-stack como Next.js, es importante crear un nuevo QueryClient para cada solicitud. Esto evita que tus usuarios compartan la misma caché. Puedes usar createTRPCContext para crear un conjunto de proveedores y consumidores de contexto con seguridad de tipos a partir de la firma de tipos de tu AppRouter.

utils/trpc.ts
tsx
import { createTRPCContext } from '@trpc/tanstack-react-query';
import type { AppRouter } from '../server/router';
 
export const { TRPCProvider, useTRPC, useTRPCClient } = createTRPCContext<AppRouter>();
utils/trpc.ts
tsx
import { createTRPCContext } from '@trpc/tanstack-react-query';
import type { AppRouter } from '../server/router';
 
export const { TRPCProvider, useTRPC, useTRPCClient } = createTRPCContext<AppRouter>();

Luego, crea un cliente tRPC y envuelve tu aplicación en TRPCProvider como se muestra abajo. También necesitarás configurar y conectar React Query, lo cual documentan con más profundidad.

consejo

Si ya usas React Query en tu aplicación, deberías reutilizar el QueryClient y QueryClientProvider que ya tienes. Puedes leer más sobre la inicialización de QueryClient en la documentación de React Query.

components/App.tsx
tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { createTRPCClient, httpBatchLink } from '@trpc/client';
import { useState } from 'react';
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}>
{/* Your app here */}
</TRPCProvider>
</QueryClientProvider>
);
}
components/App.tsx
tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { createTRPCClient, httpBatchLink } from '@trpc/client';
import { useState } from 'react';
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}>
{/* Your app here */}
</TRPCProvider>
</QueryClientProvider>
);
}

3b. Configurar con prefijo de claves para consultas/mutaciones activado

Si deseas agregar un prefijo específico a todas tus consultas y mutaciones, consulta Prefijo de claves para ver ejemplos de configuración y uso.

3c. Configurar sin contexto de React

Al construir una SPA usando solo renderizado del lado del cliente con herramientas como Vite, puedes crear el QueryClient y el cliente tRPC fuera del contexto de React como singletons.

utils/trpc.ts
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,
});
utils/trpc.ts
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,
});
components/App.tsx
tsx
import { QueryClientProvider } from '@tanstack/react-query';
import React from 'react';
import { queryClient } from './utils/trpc';
export function App() {
return (
<QueryClientProvider client={queryClient}>
{/* Your app here */}
</QueryClientProvider>
);
}
components/App.tsx
tsx
import { QueryClientProvider } from '@tanstack/react-query';
import React from 'react';
import { queryClient } from './utils/trpc';
export function App() {
return (
<QueryClientProvider client={queryClient}>
{/* Your app here */}
</QueryClientProvider>
);
}

4. Obtener datos

Ahora puedes usar la integración de tRPC con React Query para llamar a consultas y mutaciones en tu API.

components/user-list.tsx
tsx
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>
);
}
components/user-list.tsx
tsx
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>
);
}