useUtils
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
useUtils es un hook que te da acceso a utilidades para gestionar los datos en caché de las consultas que ejecutas mediante @trpc/react-query. Estas utilidades son envoltorios ligeros alrededor de los métodos del queryClient de @tanstack/react-query. Si necesitas información más detallada sobre opciones y patrones de uso para los helpers de useUtils que la que proporcionamos aquí, enlazaremos a la documentación correspondiente de @tanstack/react-query para que puedas consultarla.
Este hook se llamaba useContext() hasta la versión 10.41.0 (y sigue siendo un alias por el momento)
Uso
useUtils devuelve un objeto con todas las consultas disponibles en tus routers. Se usa de la misma forma que tu objeto cliente trpc. Cuando accedes a una consulta específica, obtendrás acceso a las utilidades de consulta. Por ejemplo, supongamos que tienes un router post con una consulta all:
server.tstsimport {initTRPC } from '@trpc/server';import {z } from 'zod';constt =initTRPC .create ();constappRouter =t .router ({post :t .router ({all :t .procedure .query (() => {return {posts : [{id : 1,title : 'everlong' },{id : 2,title : 'After Dark' },],};}),}),});export typeAppRouter = typeofappRouter ;
server.tstsimport {initTRPC } from '@trpc/server';import {z } from 'zod';constt =initTRPC .create ();constappRouter =t .router ({post :t .router ({all :t .procedure .query (() => {return {posts : [{id : 1,title : 'everlong' },{id : 2,title : 'After Dark' },],};}),}),});export typeAppRouter = typeofappRouter ;
¡Ahora en nuestro componente, al navegar por el objeto que nos proporciona useUtils y acceder a la consulta post.all, tendremos acceso a nuestras utilidades de consulta!
MyComponent.tsxtsximport {createTRPCReact } from '@trpc/react-query';import type {AppRouter } from './server';consttrpc =createTRPCReact <AppRouter >();functionMyComponent () {constutils =trpc .useUtils ();utils .post .all .f ;}
MyComponent.tsxtsximport {createTRPCReact } from '@trpc/react-query';import type {AppRouter } from './server';consttrpc =createTRPCReact <AppRouter >();functionMyComponent () {constutils =trpc .useUtils ();utils .post .all .f ;}
Utilidades
Estas son las utilidades a las que tendrás acceso mediante useUtils. La siguiente tabla te ayudará a identificar qué utilidad de tRPC envuelve qué método de @tanstack/react-query. Cada método de react-query enlazará a su documentación/guía correspondiente:
| tRPC helper wrapper | @tanstack/react-query helper method |
|---|---|
fetch | queryClient.fetchQuery |
prefetch | queryClient.prefetchQuery |
fetchInfinite | queryClient.fetchInfiniteQuery |
prefetchInfinite | queryClient.prefetchInfiniteQuery |
ensureData | queryClient.ensureData |
invalidate | queryClient.invalidateQueries |
refetch | queryClient.refetchQueries |
cancel | queryClient.cancelQueries |
setData | queryClient.setQueryData |
setQueriesData | queryClient.setQueriesData |
getData | queryClient.getQueryData |
setInfiniteData | queryClient.setInfiniteQueryData |
getInfiniteData | queryClient.getInfiniteData |
setMutationDefaults | queryClient.setMutationDefaults |
getMutationDefaults | queryClient.getMutationDefaults |
isMutating | queryClient.isMutating |
reset | queryClient.resetQueries |
❓ ¡La función que busco no está aquí!
@tanstack/react-query tiene muchas funciones que aún no hemos incorporado al contexto de tRPC. Si necesitas una función que no está aquí, no dudes en abrir una solicitud de función.
Mientras tanto, puedes importar y usar la función directamente desde @tanstack/react-query. También ofrecemos getQueryKey que puedes usar para obtener el queryKey correcto en los filtros al utilizar estas funciones.
Cliente proxy
Además de las utilidades de react-query mencionadas, el contexto también expone tu cliente proxy de tRPC. Esto te permite llamar a tus procedimientos con async/await sin necesidad de crear un cliente vanilla adicional.
tsximport {useState } from 'react';import {trpc } from './utils/trpc';functionMyComponent () {const [apiKey ,setApiKey ] =useState ('');constutils =trpc .useUtils ();return (<form onSubmit ={async (event ) => {constapiKey = awaitutils .client .apiKey .create .mutate ();setApiKey (apiKey );}}>{/* form content */}</form >);}
tsximport {useState } from 'react';import {trpc } from './utils/trpc';functionMyComponent () {const [apiKey ,setApiKey ] =useState ('');constutils =trpc .useUtils ();return (<form onSubmit ={async (event ) => {constapiKey = awaitutils .client .apiKey .create .mutate ();setApiKey (apiKey );}}>{/* form content */}</form >);}
Invalidación de consultas
Invalidas consultas mediante la utilidad invalidate. invalidate es especial porque, a diferencia de otras utilidades, está disponible en todos los niveles del mapa de routers. Esto significa que puedes ejecutar invalidate en una consulta individual, en un router completo o en todos los routers si lo deseas. Profundizaremos más en las siguientes secciones.
Invalidando una única consulta
Puedes invalidar una consulta relacionada con un único procedimiento e incluso filtrar según los datos de entrada para evitar llamadas innecesarias al backend.
Código de ejemplo
tsximport {trpc } from './utils/trpc';functionMyComponent () {constutils =trpc .useUtils ();constmutation =trpc .post .edit .useMutation ({onSuccess (input ) {utils .post .all .invalidate ();utils .post .byId .invalidate ({id :input .id }); // Will not invalidate queries for other id's},});// [...]}
tsximport {trpc } from './utils/trpc';functionMyComponent () {constutils =trpc .useUtils ();constmutation =trpc .post .edit .useMutation ({onSuccess (input ) {utils .post .all .invalidate ();utils .post .byId .invalidate ({id :input .id }); // Will not invalidate queries for other id's},});// [...]}
Invalidando en routers completos
También es posible invalidar consultas en un router completo, no solo en una consulta individual.
Código de ejemplo
Backend code
server/routers/_app.tstsximport {initTRPC } from '@trpc/server';import {z } from 'zod';export constt =initTRPC .create ();export constappRouter =t .router ({// sub Post routerpost :t .router ({all :t .procedure .query (() => {return {posts : [{id : 1,title : 'everlong' },{id : 2,title : 'After Dark' },],};}),byId :t .procedure .input (z .object ({id :z .string (),}),).query (({input }) => {return {post : {id :input ?.id ,title : 'Look me up!' },};}),edit :t .procedure .input (z .object ({id :z .number (),title :z .string () })).mutation (({input }) => {return {post : {id :input .id ,title :input .title } };}),}),// separate user routeruser :t .router ({all :t .procedure .query (() => {return {users : [{name : 'Dave Grohl' }, {name : 'Haruki Murakami' }] };}),}),});
server/routers/_app.tstsximport {initTRPC } from '@trpc/server';import {z } from 'zod';export constt =initTRPC .create ();export constappRouter =t .router ({// sub Post routerpost :t .router ({all :t .procedure .query (() => {return {posts : [{id : 1,title : 'everlong' },{id : 2,title : 'After Dark' },],};}),byId :t .procedure .input (z .object ({id :z .string (),}),).query (({input }) => {return {post : {id :input ?.id ,title : 'Look me up!' },};}),edit :t .procedure .input (z .object ({id :z .number (),title :z .string () })).mutation (({input }) => {return {post : {id :input .id ,title :input .title } };}),}),// separate user routeruser :t .router ({all :t .procedure .query (() => {return {users : [{name : 'Dave Grohl' }, {name : 'Haruki Murakami' }] };}),}),});
tsximport {trpc } from './utils/trpc';functionMyComponent () {constutils =trpc .useUtils ();constinvalidateAllQueriesAcrossAllRouters = () => {// 1️⃣// All queries on all routers will be invalidatedutils .invalidate ();};constinvalidateAllPostQueries = () => {// 2️⃣// All post queries will be invalidatedutils .post .invalidate ();};constinvalidatePostById = () => {// 3️⃣// All queries in the post router with input {id:1} invalidatedutils .post .byId .invalidate ({id : 1 });};// Example queriestrpc .user .all .useQuery (); // Would only be validated by 1️⃣ only.trpc .post .all .useQuery (); // Would be invalidated by 1️⃣ & 2️⃣trpc .post .byId .useQuery ({id : 1 }); // Would be invalidated by 1️⃣, 2️⃣ and 3️⃣trpc .post .byId .useQuery ({id : 2 }); // would be invalidated by 1️⃣ and 2️⃣ but NOT 3️⃣!// [...]}
tsximport {trpc } from './utils/trpc';functionMyComponent () {constutils =trpc .useUtils ();constinvalidateAllQueriesAcrossAllRouters = () => {// 1️⃣// All queries on all routers will be invalidatedutils .invalidate ();};constinvalidateAllPostQueries = () => {// 2️⃣// All post queries will be invalidatedutils .post .invalidate ();};constinvalidatePostById = () => {// 3️⃣// All queries in the post router with input {id:1} invalidatedutils .post .byId .invalidate ({id : 1 });};// Example queriestrpc .user .all .useQuery (); // Would only be validated by 1️⃣ only.trpc .post .all .useQuery (); // Would be invalidated by 1️⃣ & 2️⃣trpc .post .byId .useQuery ({id : 1 }); // Would be invalidated by 1️⃣, 2️⃣ and 3️⃣trpc .post .byId .useQuery ({id : 2 }); // would be invalidated by 1️⃣ and 2️⃣ but NOT 3️⃣!// [...]}
Invalidar toda la caché en cada mutación
Hacer un seguimiento exacto de qué consultas debería invalidar una mutación es complejo, por lo que invalidar la caché completa como efecto secundario de cualquier mutación puede ser una solución pragmática. Gracias a la agrupación de solicitudes, esta invalidación simplemente volverá a obtener todas las consultas de la página actual en una única petición.
Hemos añadido una función para ayudar con esto:
tsimport {createTRPCReact } from '@trpc/react-query';import type {AppRouter } from '../server';export consttrpc =createTRPCReact <AppRouter >({overrides : {useMutation : {/*** This function is called whenever a `.useMutation` succeeds**/asynconSuccess (opts ) {/*** @note that order here matters:* The order here allows route changes in `onSuccess` without* having a flash of content change whilst redirecting.**/// Calls the `onSuccess` defined in the `useQuery()`-options:awaitopts .originalFn ();// Invalidate all queries in the react-query cache:awaitopts .queryClient .invalidateQueries ();},},},});
tsimport {createTRPCReact } from '@trpc/react-query';import type {AppRouter } from '../server';export consttrpc =createTRPCReact <AppRouter >({overrides : {useMutation : {/*** This function is called whenever a `.useMutation` succeeds**/asynconSuccess (opts ) {/*** @note that order here matters:* The order here allows route changes in `onSuccess` without* having a flash of content change whilst redirecting.**/// Calls the `onSuccess` defined in the `useQuery()`-options:awaitopts .originalFn ();// Invalidate all queries in the react-query cache:awaitopts .queryClient .invalidateQueries ();},},},});
Opciones adicionales
Además de las utilidades de consulta, el objeto que devuelve useUtils también contiene las siguientes propiedades:
tsinterfaceProxyTRPCContextProps <TRouter extendsAnyRouter ,TSSRContext > {/*** The `TRPCClient`*/client :TRPCClient <TRouter >;/*** The SSR context when server-side rendering* @default null*/ssrContext ?:TSSRContext | null;/*** State of SSR hydration.* - `false` if not using SSR.* - `prepass` when doing a prepass to fetch queries' data* - `mounting` before TRPCProvider has been rendered on the client* - `mounted` when the TRPCProvider has been rendered on the client* @default false*/ssrState ?:SSRState ;/*** Abort loading query calls when unmounting a component - usually when navigating to a new page* @default false*/abortOnUnmount ?: boolean;}
tsinterfaceProxyTRPCContextProps <TRouter extendsAnyRouter ,TSSRContext > {/*** The `TRPCClient`*/client :TRPCClient <TRouter >;/*** The SSR context when server-side rendering* @default null*/ssrContext ?:TSSRContext | null;/*** State of SSR hydration.* - `false` if not using SSR.* - `prepass` when doing a prepass to fetch queries' data* - `mounting` before TRPCProvider has been rendered on the client* - `mounted` when the TRPCProvider has been rendered on the client* @default false*/ssrState ?:SSRState ;/*** Abort loading query calls when unmounting a component - usually when navigating to a new page* @default false*/abortOnUnmount ?: boolean;}