useUtils
Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →
useUtils est un hook qui vous donne accès à des assistants permettant de gérer les données en cache des requêtes exécutées via @trpc/react-query. Ces assistants sont en réalité des wrappers légers autour des méthodes du queryClient de @tanstack/react-query. Si vous souhaitez des informations plus approfondies sur les options et les modèles d'utilisation des assistants useUtils que ce que nous fournissons ici, nous renverrons vers la documentation correspondante de @tanstack/react-query.
Ce hook s'appelait useContext() jusqu'à la version 10.41.0 (et conserve cet alias pour le moment)
Utilisation
useUtils retourne un objet contenant toutes les requêtes disponibles dans vos routeurs. Vous l'utilisez de la même manière que votre objet client trpc. Lorsque vous accédez à une requête, vous obtenez les assistants associés. Par exemple, supposons que vous ayez un routeur post avec une requête 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 ;
Dans notre composant, lorsque nous naviguons dans l'objet fourni par useUtils et accédons à la requête post.all, nous obtenons nos assistants de requête !
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 ;}
Assistants
Voici les assistants accessibles via useUtils. Le tableau ci-dessous indique quel assistant tRPC encapsule quelle méthode d'assistance de @tanstack/react-query. Chaque méthode react-query renvoie vers sa documentation correspondante :
| 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 fonction que je cherche n'est pas là !
@tanstack/react-query propose de nombreuses fonctions que nous n'avons pas encore intégrées au contexte tRPC. Si vous avez besoin d'une fonction manquante, n'hésitez pas à ouvrir une demande de fonctionnalité.
Entre-temps, vous pouvez importer et utiliser la fonction directement depuis @tanstack/react-query. Nous fournissons également une fonction getQueryKey que vous pouvez utiliser pour obtenir le queryKey correct dans les filtres lors de l'utilisation de ces fonctions.
Client proxy
En plus des assistants react-query ci-dessus, le contexte expose également votre client proxy tRPC. Cela vous permet d'appeler vos procédures avec async/await sans créer de client vanilla supplémentaire.
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 >);}
Invalidation de requêtes
L'invalidation de requêtes s'effectue via l'assistant invalidate. invalidate est un assistant particulier car, contrairement aux autres, il est disponible à tous les niveaux de la structure des routeurs. Vous pouvez ainsi lancer invalidate sur une requête unique, un routeur entier, ou tous les routeurs. Nous détaillons cela ci-dessous.
Invalider une requête unique
Vous pouvez invalider une requête liée à une procédure spécifique, et même filtrer selon les paramètres d'entrée pour éviter des appels inutiles au back-end.
Exemple de code
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},});// [...]}
Invalider plusieurs routeurs
Il est également possible d'invalider des requêtes sur un routeur entier plutôt que sur une seule requête.
Exemple de code
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️⃣!// [...]}
Invalider tout le cache à chaque mutation
Suivre précisément quelles requêtes une mutation devrait invalider est complexe. Une solution pragmatique consiste à invalider le cache complet comme effet secondaire de toute mutation. Grâce au batching de requêtes, cette invalidation rafraîchira toutes les requêtes de la page courante en une seule requête.
Nous avons ajouté une fonctionnalité pour faciliter cela :
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 ();},},},});
Options supplémentaires
Outre les assistants de requêtes, l'objet retourné par useUtils contient également les propriétés suivantes :
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;}