TanStack React Query
このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →
クイッククエリの例
tsximport {useQuery } from '@tanstack/react-query';import {useTRPC } from './trpc';functionUsers () {consttrpc =useTRPC ();constgreetingQuery =useQuery (trpc .greeting .queryOptions ({name : 'Jerry' }));// greetingQuery.data === 'Hello Jerry'}
tsximport {useQuery } from '@tanstack/react-query';import {useTRPC } from './trpc';functionUsers () {consttrpc =useTRPC ();constgreetingQuery =useQuery (trpc .greeting .queryOptions ({name : 'Jerry' }));// greetingQuery.data === 'Hello Jerry'}
使用方法
このクライアントの設計思想は、TanStack React Query とネイティブかつ型安全に連携する薄型の型安全ファクトリーを提供することです。つまりクライアントが提供するオートコンプリートに従うだけで、TanStack React Query ドキュメントの知識に基づいて開発に集中できます。
tsxexport default functionBasics () {consttrpc =useTRPC ();constqueryClient =useQueryClient ();// Create QueryOptions which can be passed to query hooksconstmyQueryOptions =trpc .path .to .query .queryOptions ({ /** inputs */ })constmyQuery =useQuery (myQueryOptions )// or:// useSuspenseQuery(myQueryOptions)// useInfiniteQuery(myQueryOptions)// Create MutationOptions which can be passed to useMutationconstmyMutationOptions =trpc .path .to .mutation .mutationOptions ()constmyMutation =useMutation (myMutationOptions )// Create a QueryKey which can be used to manipulate many methods// on TanStack's QueryClient in a type-safe mannerconstmyQueryKey =trpc .path .to .query .queryKey ()constinvalidateMyQueryKey = () => {queryClient .invalidateQueries ({queryKey :myQueryKey })}return (// Your app herenull)}
tsxexport default functionBasics () {consttrpc =useTRPC ();constqueryClient =useQueryClient ();// Create QueryOptions which can be passed to query hooksconstmyQueryOptions =trpc .path .to .query .queryOptions ({ /** inputs */ })constmyQuery =useQuery (myQueryOptions )// or:// useSuspenseQuery(myQueryOptions)// useInfiniteQuery(myQueryOptions)// Create MutationOptions which can be passed to useMutationconstmyMutationOptions =trpc .path .to .mutation .mutationOptions ()constmyMutation =useMutation (myMutationOptions )// Create a QueryKey which can be used to manipulate many methods// on TanStack's QueryClient in a type-safe mannerconstmyQueryKey =trpc .path .to .query .queryKey ()constinvalidateMyQueryKey = () => {queryClient .invalidateQueries ({queryKey :myQueryKey })}return (// Your app herenull)}
trpcオブジェクトは完全に型安全で、AppRouter内の全プロシージャに対してオートコンプリートを提供します。プロキシの末端では以下のメソッドが利用可能です:
queryOptions - データクエリ
全クエリプロシージャで利用可能です。TanStackのqueryOptions関数を型安全にラップします。第一引数はプロシージャへの入力、第二引数はTanStack React Queryの任意のネイティブオプションを受け付けます。
tsconstqueryOptions =trpc .path .to .query .queryOptions ({/** input */id : 'foo',},{// Any Tanstack React Query optionsstaleTime : 1000,},);
tsconstqueryOptions =trpc .path .to .query .queryOptions ({/** input */id : 'foo',},{// Any Tanstack React Query optionsstaleTime : 1000,},);
queryOptions関数にtrpcオブジェクトを追加で渡すことで、クライアントにtRPCリクエストオプションを提供できます。
tsconstqueryOptions =trpc .path .to .query .queryOptions ({/** input */id : 'foo',},{trpc : {// Provide tRPC request options to the clientcontext : {// see https://trpc.io/docs/client/links#managing-context},},},);
tsconstqueryOptions =trpc .path .to .query .queryOptions ({/** input */id : 'foo',},{trpc : {// Provide tRPC request options to the clientcontext : {// see https://trpc.io/docs/client/links#managing-context},},},);
型安全な方法でクエリを無効化したい場合、skipTokenが使用できます:
tsconstquery =useQuery (trpc .user .details .queryOptions (user ?.id &&project ?.id ? {userId :user .id ,projectId :project .id ,}:skipToken ,{staleTime : 1000,},),);
tsconstquery =useQuery (trpc .user .details .queryOptions (user ?.id &&project ?.id ? {userId :user .id ,projectId :project .id ,}:skipToken ,{staleTime : 1000,},),);
結果はuseQueryやuseSuspenseQueryフック、あるいはfetchQuery、prefetchQuery、prefetchInfiniteQuery、invalidateQueriesなどのクエリクライアントメソッドに渡せます。
infiniteQueryOptions - 無限データクエリ
カーソル入力を受け取る全クエリプロシージャで利用可能です。TanStackのinfiniteQueryOptions関数を型安全にラップします。第一引数はプロシージャへの入力、第二引数はTanStack React Queryの任意のネイティブオプションを受け付けます。
tsconstinfiniteQueryOptions =trpc .path .to .query .infiniteQueryOptions ({/** input */},{// Any Tanstack React Query optionsgetNextPageParam : (lastPage ,pages ) =>lastPage .nextCursor ,},);
tsconstinfiniteQueryOptions =trpc .path .to .query .infiniteQueryOptions ({/** input */},{// Any Tanstack React Query optionsgetNextPageParam : (lastPage ,pages ) =>lastPage .nextCursor ,},);
queryKey - クエリキーの取得とクエリクライアント操作
全クエリプロシージャで利用可能です。型安全な方法でクエリキーにアクセスできます。
tsconstqueryKey =trpc .path .to .query .queryKey ();
tsconstqueryKey =trpc .path .to .query .queryKey ();
TanStack React Queryはクエリキーにファジーマッチングを使用するため、ルーターに属する全クエリにマッチさせる任意のサブパスの部分クエリキーを作成できます:
tsconstqueryKey =trpc .router .pathKey ();
tsconstqueryKey =trpc .router .pathKey ();
全tRPCクエリにマッチさせるルートパスも指定可能です:
tsconstqueryKey =trpc .pathKey ();
tsconstqueryKey =trpc .pathKey ();
infiniteQueryKey - 無限クエリキーの取得
カーソル入力を受け取る全クエリプロシージャで利用可能です。型安全な方法で無限クエリのクエリキーにアクセスできます。
tsconstinfiniteQueryKey =trpc .path .to .query .infiniteQueryKey ({/** input */});
tsconstinfiniteQueryKey =trpc .path .to .query .infiniteQueryKey ({/** input */});
結果はgetQueryData、setQueryData、invalidateQueriesなどのクエリクライアントメソッドで使用できます。
ts// Get cached data for an infinite queryconstcachedData =queryClient .getQueryData (trpc .path .to .query .infiniteQueryKey ({cursor : 0 }),);// Set cached data for an infinite queryqueryClient .setQueryData (trpc .path .to .query .infiniteQueryKey ({cursor : 0 }),(data ) => {// Modify the datareturndata ;},);
ts// Get cached data for an infinite queryconstcachedData =queryClient .getQueryData (trpc .path .to .query .infiniteQueryKey ({cursor : 0 }),);// Set cached data for an infinite queryqueryClient .setQueryData (trpc .path .to .query .infiniteQueryKey ({cursor : 0 }),(data ) => {// Modify the datareturndata ;},);
queryFilter - クエリフィルター作成
全クエリプロシージャで利用可能です。型安全な方法でクエリフィルターを作成できます。
tsconstqueryFilter =trpc .path .to .query .queryFilter ({/** input */},{// Any Tanstack React Query filterpredicate : (query ) => {return !!query .state .data ;},},);
tsconstqueryFilter =trpc .path .to .query .queryFilter ({/** input */},{// Any Tanstack React Query filterpredicate : (query ) => {return !!query .state .data ;},},);
クエリキーと同様に、ルーター全体にフィルターを適用したい場合、任意のサブパスを対象とするpathFilterを使用できます。
tsconstqueryFilter =trpc .path .pathFilter ({// Any Tanstack React Query filterpredicate : (query ) => {return !!query .state .data ;},});
tsconstqueryFilter =trpc .path .pathFilter ({// Any Tanstack React Query filterpredicate : (query ) => {return !!query .state .data ;},});
queryClient.invalidateQueriesなどのクライアントメソッドに渡せるフィルター作成に有用です。
infiniteQueryFilter - 無限クエリフィルター作成
カーソル入力を受け取る全クエリプロシージャで利用可能です。型安全な方法で無限クエリ向けのクエリフィルターを作成できます。
tsconstinfiniteQueryFilter =trpc .path .to .query .infiniteQueryFilter ({/** input */},{// Any Tanstack React Query filterpredicate : (query ) => {return !!query .state .data ;},},);
tsconstinfiniteQueryFilter =trpc .path .to .query .infiniteQueryFilter ({/** input */},{// Any Tanstack React Query filterpredicate : (query ) => {return !!query .state .data ;},},);
queryClient.invalidateQueriesなどのクライアントメソッドに渡せるフィルター作成に有用です。
tsawaitqueryClient .invalidateQueries (trpc .path .to .query .infiniteQueryFilter ({},{predicate : (query ) => {// Filter logic based on query statereturnquery .state .status === 'success';},},),);
tsawaitqueryClient .invalidateQueries (trpc .path .to .query .infiniteQueryFilter ({},{predicate : (query ) => {// Filter logic based on query statereturnquery .state .status === 'success';},},),);
mutationOptions - ミューテーションオプション作成
全ミューテーションプロシージャで利用可能です。useMutationに渡せるオプションを構築するための型安全な恒等関数を提供します。
tsconstmutationOptions =trpc .path .to .mutation .mutationOptions ({// Any Tanstack React Query optionsonSuccess : (data ) => {// do something with the data},});
tsconstmutationOptions =trpc .path .to .mutation .mutationOptions ({// Any Tanstack React Query optionsonSuccess : (data ) => {// do something with the data},});
mutationKey - ミューテーションキー取得
全ミューテーションプロシージャで利用可能です。型安全な方法でミューテーションキーを取得できます。
tsconstmutationKey =trpc .path .to .mutation .mutationKey ();
tsconstmutationKey =trpc .path .to .mutation .mutationKey ();
subscriptionOptions - サブスクリプションオプション作成
TanStackはサブスクリプションフックを提供していないため、標準的なtRPCサブスクリプション設定と連携する独自の抽象化レイヤーを維持しています。
全サブスクリプションプロシージャで利用可能です。useSubscriptionに渡せるオプションを構築するための型安全な恒等関数を提供します。
サブスクリプションを使用するには、tRPCクライアントにhttpSubscriptionLinkまたはwsLinkのいずれかを設定する必要があります。
tsxfunctionSubscriptionExample () {consttrpc =useTRPC ();constsubscription =useSubscription (trpc .path .to .subscription .subscriptionOptions ({/** input */},{enabled : true,onStarted : () => {// do something when the subscription is started},onData : (data ) => {// you can handle the data here},onError : (error ) => {// you can handle the error here},onConnectionStateChange : (state ) => {// you can handle the connection state here},},),);// Or you can handle the state heresubscription .data ; // The lastly received datasubscription .error ; // The lastly received error/*** The current status of the subscription.* Will be one of: `'idle'`, `'connecting'`, `'pending'`, or `'error'`.** - `idle`: subscription is disabled or ended* - `connecting`: trying to establish a connection* - `pending`: connected to the server, receiving data* - `error`: an error occurred and the subscription is stopped*/subscription .status ;// Reset the subscription (if you have an error etc)subscription .reset ();return <>{/* ... */}</>;}
tsxfunctionSubscriptionExample () {consttrpc =useTRPC ();constsubscription =useSubscription (trpc .path .to .subscription .subscriptionOptions ({/** input */},{enabled : true,onStarted : () => {// do something when the subscription is started},onData : (data ) => {// you can handle the data here},onError : (error ) => {// you can handle the error here},onConnectionStateChange : (state ) => {// you can handle the connection state here},},),);// Or you can handle the state heresubscription .data ; // The lastly received datasubscription .error ; // The lastly received error/*** The current status of the subscription.* Will be one of: `'idle'`, `'connecting'`, `'pending'`, or `'error'`.** - `idle`: subscription is disabled or ended* - `connecting`: trying to establish a connection* - `pending`: connected to the server, receiving data* - `error`: an error occurred and the subscription is stopped*/subscription .status ;// Reset the subscription (if you have an error etc)subscription .reset ();return <>{/* ... */}</>;}
クエリキープレフィックス
単一アプリケーション内で複数のtRPCプロバイダーを使用する場合(例: 異なるバックエンドサービスへの接続)、同じパスを持つクエリはキャッシュで衝突する可能性があります。クエリキープレフィックスを有効化することでこの問題を防げます。
tsx// Without prefixes - these would collide!constauthQuery =useQuery (trpcAuth .list .queryOptions ()); // auth serviceconstbillingQuery =useQuery (trpcBilling .list .queryOptions ()); // billing service
tsx// Without prefixes - these would collide!constauthQuery =useQuery (trpcAuth .list .queryOptions ()); // auth serviceconstbillingQuery =useQuery (trpcBilling .list .queryOptions ()); // billing service
コンテキスト作成時に機能フラグを有効にします:
utils/trpc.tstsx// [...]constbilling =createTRPCContext <BillingRouter , {keyPrefix : true }>();export constBillingProvider =billing .TRPCProvider ;export constuseBilling =billing .useTRPC ;export constcreateBillingClient = () =>createTRPCClient <BillingRouter >({links : [/* ... */],});constaccount =createTRPCContext <AccountRouter , {keyPrefix : true }>();export constAccountProvider =account .TRPCProvider ;export constuseAccount =account .useTRPC ;export constcreateAccountClient = () =>createTRPCClient <AccountRouter >({links : [/* ... */],});
utils/trpc.tstsx// [...]constbilling =createTRPCContext <BillingRouter , {keyPrefix : true }>();export constBillingProvider =billing .TRPCProvider ;export constuseBilling =billing .useTRPC ;export constcreateBillingClient = () =>createTRPCClient <BillingRouter >({links : [/* ... */],});constaccount =createTRPCContext <AccountRouter , {keyPrefix : true }>();export constAccountProvider =account .TRPCProvider ;export constuseAccount =account .useTRPC ;export constcreateAccountClient = () =>createTRPCClient <AccountRouter >({links : [/* ... */],});
App.tsxtsximport {useState } from 'react';import {QueryClient ,QueryClientProvider } from '@tanstack/react-query';import {BillingProvider ,AccountProvider ,createBillingClient ,createAccountClient ,} from './utils/trpc';// [...]export functionApp () {const [queryClient ] =useState (() => newQueryClient ());const [billingClient ] =useState (() =>createBillingClient ());const [accountClient ] =useState (() =>createAccountClient ());return (<QueryClientProvider client ={queryClient }><BillingProvider trpcClient ={billingClient }queryClient ={queryClient }keyPrefix ="billing"><AccountProvider trpcClient ={accountClient }queryClient ={queryClient }keyPrefix ="account"><div >{/* ... */}</div ></AccountProvider ></BillingProvider ></QueryClientProvider >);}
App.tsxtsximport {useState } from 'react';import {QueryClient ,QueryClientProvider } from '@tanstack/react-query';import {BillingProvider ,AccountProvider ,createBillingClient ,createAccountClient ,} from './utils/trpc';// [...]export functionApp () {const [queryClient ] =useState (() => newQueryClient ());const [billingClient ] =useState (() =>createBillingClient ());const [accountClient ] =useState (() =>createAccountClient ());return (<QueryClientProvider client ={queryClient }><BillingProvider trpcClient ={billingClient }queryClient ={queryClient }keyPrefix ="billing"><AccountProvider trpcClient ={accountClient }queryClient ={queryClient }keyPrefix ="account"><div >{/* ... */}</div ></AccountProvider ></BillingProvider ></QueryClientProvider >);}
components/MyComponent.tsxtsximport {useQuery } from '@tanstack/react-query';import {useBilling ,useAccount } from '../utils/trpc';// [...]export functionMyComponent () {constbilling =useBilling ();constaccount =useAccount ();constbillingList =useQuery (billing .list .queryOptions ());constaccountList =useQuery (account .list .queryOptions ());return (<div ><div >Billing: {JSON .stringify (billingList .data ?? null)}</div ><div >Account: {JSON .stringify (accountList .data ?? null)}</div ></div >);}
components/MyComponent.tsxtsximport {useQuery } from '@tanstack/react-query';import {useBilling ,useAccount } from '../utils/trpc';// [...]export functionMyComponent () {constbilling =useBilling ();constaccount =useAccount ();constbillingList =useQuery (billing .list .queryOptions ());constaccountList =useQuery (account .list .queryOptions ());return (<div ><div >Billing: {JSON .stringify (billingList .data ?? null)}</div ><div >Account: {JSON .stringify (accountList .data ?? null)}</div ></div >);}
クエリキーには衝突を回避するため適切にプレフィックスが付与されます:
tsx// Example of how the query keys look with prefixesconstqueryKeys = [[['billing'], ['list'], {type : 'query' }],[['account'], ['list'], {type : 'query' }],];
tsx// Example of how the query keys look with prefixesconstqueryKeys = [[['billing'], ['list'], {type : 'query' }],[['account'], ['list'], {type : 'query' }],];
入力と出力の型の推論
プロシージャやルーターの入力と出力の型を推論する必要がある場合、状況に応じて2つのオプションが利用可能です。
ルーター全体の入力と出力の型の推論
tsimport type {inferRouterInputs ,inferRouterOutputs } from '@trpc/server';import type {AppRouter } from './server/router';export typeInputs =inferRouterInputs <AppRouter >;export typeOutputs =inferRouterOutputs <AppRouter >;
tsimport type {inferRouterInputs ,inferRouterOutputs } from '@trpc/server';import type {AppRouter } from './server/router';export typeInputs =inferRouterInputs <AppRouter >;export typeOutputs =inferRouterOutputs <AppRouter >;
単一プロシージャの型推論
tsimport type {inferInput ,inferOutput } from '@trpc/tanstack-react-query';functionComponent () {consttrpc =useTRPC ();typeInput =inferInput <typeoftrpc .path .to .procedure >;typeOutput =inferOutput <typeoftrpc .path .to .procedure >;}
tsimport type {inferInput ,inferOutput } from '@trpc/tanstack-react-query';functionComponent () {consttrpc =useTRPC ();typeInput =inferInput <typeoftrpc .path .to .procedure >;typeOutput =inferOutput <typeoftrpc .path .to .procedure >;}
tRPCクライアントへのアクセス
React Contextを使用したセットアップを行った場合、useTRPCClientフックを使用してtRPCクライアントにアクセスできます。
tsximport {useTRPCClient } from './trpc';async functionComponent () {consttrpcClient =useTRPCClient ();constresult = awaittrpcClient .getUser .query ({id : '1',});}
tsximport {useTRPCClient } from './trpc';async functionComponent () {consttrpcClient =useTRPCClient ();constresult = awaittrpcClient .getUser .query ({id : '1',});}
React Contextを使用しないセットアップを行った場合、代わりにグローバルクライアントインスタンスを直接インポートできます。
tsimport {client } from './trpc';constresult = awaitclient .path .to .procedure .query ({/** input */id : 'foo',});
tsimport {client } from './trpc';constresult = awaitclient .path .to .procedure .query ({/** input */id : 'foo',});