Aller au contenu principal
Version : 11.x

useQuery()

Traduction Bêta Non Officielle

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 →

useQuery est le hook principal pour la récupération de données. Il fonctionne similairement au useQuery de @tanstack/react-query, mais avec des options spécifiques à trpc et des fonctionnalités supplémentaires comme le streaming.

note

Pour des informations détaillées sur les options et les modèles d'utilisation, consultez la documentation TanStack Query sur les requêtes.

Signature

tsx
function useQuery(
input: TInput | SkipToken,
opts?: UseTRPCQueryOptions;
)
interface UseTRPCQueryOptions
extends UseQueryOptions {
trpc: {
ssr?: boolean;
abortOnUnmount?: boolean;
context?: Record<string, unknown>;
}
}
tsx
function useQuery(
input: TInput | SkipToken,
opts?: UseTRPCQueryOptions;
)
interface UseTRPCQueryOptions
extends UseQueryOptions {
trpc: {
ssr?: boolean;
abortOnUnmount?: boolean;
context?: Record<string, unknown>;
}
}

Comme UseTRPCQueryOptions étend UseQueryOptions de @tanstack/react-query, vous pouvez utiliser toutes leurs options ici comme enabled, refetchOnWindowFocus, etc. Nous avons également des options spécifiques à trpc qui vous permettent d'activer ou désactiver certains comportements au niveau de chaque procédure :

  • trpc.ssr: Si vous avez ssr: true dans votre configuration globale, vous pouvez définir cette option sur false pour désactiver le SSR pour cette requête spécifique. Notez que l'inverse n'est pas possible : vous ne pouvez pas activer le SSR sur une procédure si votre configuration globale est définie sur false.

  • trpc.abortOnUnmount: Surcharge la configuration globale pour activer ou désactiver l'annulation des requêtes lors du démontage du composant.

  • trpc.context: Ajoute des métadonnées supplémentaires pouvant être utilisées dans les Liens.

astuce

Si vous devez définir des options mais ne souhaitez pas transmettre d'input, vous pouvez passer undefined à la place.

Vous remarquerez que vous bénéficiez de l'auto-complétion sur l'input basée sur ce que vous avez défini dans votre schéma input côté backend.

Exemple d'utilisation

Backend code
server/routers/_app.ts
tsx
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
export const t = initTRPC.create();
export const appRouter = t.router({
// Create procedure at path 'hello'
hello: t.procedure
// using zod schema to validate and infer input values
.input(
z
.object({
text: z.string().nullish(),
})
.nullish(),
)
.query((opts) => {
return {
greeting: `hello ${opts.input?.text ?? 'world'}`,
};
}),
});
server/routers/_app.ts
tsx
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
export const t = initTRPC.create();
export const appRouter = t.router({
// Create procedure at path 'hello'
hello: t.procedure
// using zod schema to validate and infer input values
.input(
z
.object({
text: z.string().nullish(),
})
.nullish(),
)
.query((opts) => {
return {
greeting: `hello ${opts.input?.text ?? 'world'}`,
};
}),
});
components/MyComponent.tsx
tsx
import { trpc } from '../utils/trpc';
export function MyComponent() {
// input is optional, so we don't have to pass second argument
const helloNoArgs = trpc.hello.useQuery();
const helloWithArgs = trpc.hello.useQuery({ text: 'client' });
return (
<div>
<h1>Hello World Example</h1>
<ul>
<li>
helloNoArgs ({helloNoArgs.status}):{' '}
<pre>{JSON.stringify(helloNoArgs.data, null, 2)}</pre>
</li>
<li>
helloWithArgs ({helloWithArgs.status}):{' '}
<pre>{JSON.stringify(helloWithArgs.data, null, 2)}</pre>
</li>
</ul>
</div>
);
}
components/MyComponent.tsx
tsx
import { trpc } from '../utils/trpc';
export function MyComponent() {
// input is optional, so we don't have to pass second argument
const helloNoArgs = trpc.hello.useQuery();
const helloWithArgs = trpc.hello.useQuery({ text: 'client' });
return (
<div>
<h1>Hello World Example</h1>
<ul>
<li>
helloNoArgs ({helloNoArgs.status}):{' '}
<pre>{JSON.stringify(helloNoArgs.data, null, 2)}</pre>
</li>
<li>
helloWithArgs ({helloWithArgs.status}):{' '}
<pre>{JSON.stringify(helloWithArgs.data, null, 2)}</pre>
</li>
</ul>
</div>
);
}

Réponses en streaming avec des générateurs asynchrones

info

Depuis la v11, nous supportons maintenant les requêtes en streaming lors de l'utilisation du httpBatchStreamLink.

Lorsque vous retournez des générateurs asynchrones dans une requête :

  • Vous obtenez les résultats de l'itérateur dans la propriété data sous forme de tableau, qui se met à jour au fur et à mesure de la réception de la réponse

  • Le status passera à success dès la réception du premier fragment.

  • La propriété fetchStatus restera à fetching jusqu'à la réception du dernier fragment.

Exemple

server/routers/_app.ts
tsx
import { publicProcedure, router } from './trpc';
const appRouter = router({
iterable: publicProcedure.query(async function* () {
for (let i = 0; i < 3; i++) {
await new Promise((resolve) => setTimeout(resolve, 500));
yield i;
}
}),
});
export type AppRouter = typeof appRouter;
server/routers/_app.ts
tsx
import { publicProcedure, router } from './trpc';
const appRouter = router({
iterable: publicProcedure.query(async function* () {
for (let i = 0; i < 3; i++) {
await new Promise((resolve) => setTimeout(resolve, 500));
yield i;
}
}),
});
export type AppRouter = typeof appRouter;
components/MyComponent.tsx
tsx
import { trpc } from '~/utils';
export function MyComponent() {
const result = trpc.iterable.useQuery();
return (
<div>
{result.data?.map((chunk, index) => (
<Fragment key={index}>{chunk}</Fragment>
))}
</div>
);
}
components/MyComponent.tsx
tsx
import { trpc } from '~/utils';
export function MyComponent() {
const result = trpc.iterable.useQuery();
return (
<div>
{result.data?.map((chunk, index) => (
<Fragment key={index}>{chunk}</Fragment>
))}
</div>
);
}

Propriétés du result pendant le streaming :

statusfetchStatusdata
'pending''fetching'undefined
'success''fetching'[]
'success''fetching'[1]
'success''fetching'[1, 2]
'success''fetching'[1, 2, 3]
'success''idle'[1, 2, 3]