useQuery()
このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →
useQueryはデータ取得の主要なフックで、@tanstack/react-queryのuseQueryと同様に動作しますが、trpc固有のオプションやストリーミングなどの追加機能が含まれています。
オプションや使用パターンの詳細については、TanStack Queryのクエリに関するドキュメントを参照してください。
シグネチャ
tsxfunction useQuery(input: TInput | SkipToken,opts?: UseTRPCQueryOptions;)interface UseTRPCQueryOptionsextends UseQueryOptions {trpc: {ssr?: boolean;abortOnUnmount?: boolean;context?: Record<string, unknown>;}}
tsxfunction useQuery(input: TInput | SkipToken,opts?: UseTRPCQueryOptions;)interface UseTRPCQueryOptionsextends UseQueryOptions {trpc: {ssr?: boolean;abortOnUnmount?: boolean;context?: Record<string, unknown>;}}
UseTRPCQueryOptionsは@tanstack/react-queryのUseQueryOptionsを拡張しているため、enabledやrefetchOnWindowFocusなど任意のオプションが使用できます。さらに、プロシージャごとの挙動を制御するtrpc固有のオプションも提供しています:
-
trpc.ssr: グローバル設定でssr: trueにしている場合、この特定のクエリでSSRを無効化するにはfalseを設定します。逆方向の動作はサポートされていないことに注意してください。つまり、グローバル設定がfalseの場合にプロシージャレベルでSSRを有効化することはできません。 -
trpc.abortOnUnmount: グローバル設定を上書きし、アンマウント時のクエリ中断を有効/無効にします。 -
trpc.context: リンクで使用できる追加メタデータを付与します。
オプションを設定したいが入力値を渡したくない場合、代わりにundefinedを渡せます。
バックエンドで設定したinputスキーマに基づき、inputに対するオートコンプリートが機能することに気づくでしょう。
使用例
Backend code
server/routers/_app.tstsximport { 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.tstsximport { 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.tsxtsximport { trpc } from '../utils/trpc';export function MyComponent() {// input is optional, so we don't have to pass second argumentconst 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.tsxtsximport { trpc } from '../utils/trpc';export function MyComponent() {// input is optional, so we don't have to pass second argumentconst 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>);}
asyncジェネレータを用いたストリーミングレスポンス
v11以降、httpBatchStreamLink使用時にストリーミングクエリがサポートされました。
クエリでasyncジェネレータを返す場合:
-
イテレータの結果が配列として
dataプロパティにリアルタイムで更新されながら返却されます -
最初のチャンクを受信した時点で
statusはsuccessになります -
最後のチャンクを受信するまで
fetchStatusプロパティはfetching状態を維持します
例
server/routers/_app.tstsximport { 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.tstsximport { 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.tsxtsximport { 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.tsxtsximport { trpc } from '~/utils';export function MyComponent() {const result = trpc.iterable.useQuery();return (<div>{result.data?.map((chunk, index) => (<Fragment key={index}>{chunk}</Fragment>))}</div>);}
ストリーミング中のresultプロパティ:
status | fetchStatus | data |
|---|---|---|
'pending' | 'fetching' | undefined |
'success' | 'fetching' | [] |
'success' | 'fetching' | [1] |
'success' | 'fetching' | [1, 2] |
'success' | 'fetching' | [1, 2, 3] |
'success' | 'idle' | [1, 2, 3] |