メインコンテンツへスキップ
バージョン: 9.x

Reactとの連携

非公式ベータ版翻訳

このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →

情報
  • Next.jsを使用している場合は、代わりにNext.js連携ガイドをお読みください
  • Node.jsバックエンドから型を推論するには、フロントエンドとバックエンドを同一のモノレポ内に配置する必要があります

既存のReactプロジェクトにtRPCを追加

サーバーサイド

1. 依存関係のインストール

bash
yarn add @trpc/server zod
bash
yarn add @trpc/server zod
  • Zod: ほとんどの例では入力検証にZodを使用しており、必須ではありませんが強く推奨します。お好みの検証ライブラリ(YupSuperstructio-tsなど)も使用可能です。実際、parsecreatevalidateSyncメソッドを含むオブジェクトであれば動作します

2. 厳格モードの有効化

Zodを使用した入力検証を行う場合は、tsconfig.jsonで厳格モード(strict mode)を有効化してください:

json
// tsconfig.json
{
// ...
"compilerOptions": {
// ...
"strict": true
}
}
json
// tsconfig.json
{
// ...
"compilerOptions": {
// ...
"strict": true
}
}

厳格モード(strict mode)が厳しすぎる場合は、少なくともstrictNullChecksを有効にしてください:

json
// tsconfig.json
{
// ...
"compilerOptions": {
// ...
"strictNullChecks": true
}
}
json
// tsconfig.json
{
// ...
"compilerOptions": {
// ...
"strictNullChecks": true
}
}

3. appRouterの実装

クイックスタートを参照し、@trpc/serverドキュメントを読んで実装を進めてください。APIを実装してHTTP経由でリスニングする状態になったら、次のステップに進みます

クライアントサイド

tRPCはCreate React Appでも問題なく動作します!

1. 依存関係のインストール

bash
yarn add @trpc/client @trpc/server @trpc/react react-query@3
bash
yarn add @trpc/client @trpc/server @trpc/react react-query@3
  • @trpc/server: @trpc/clientのpeer dependencyなので再インストールが必要です

  • TanstackのReact Query: @trpc/reactは@tanstack/react-queryの薄いラッパーを提供します。peer dependencyとして必須です

2. tRPCフックの作成

createReactQueryHooksを使用して、AppRouterの型シグネチャから厳密に型付けされたReactフックのセットを作成します

utils/trpc.ts
tsx
// utils/trpc.ts
import { createReactQueryHooks } from '@trpc/react';
import type { AppRouter } from '../path/to/router.ts';
export const trpc = createReactQueryHooks<AppRouter>();
// => { useQuery: ..., useMutation: ...}
utils/trpc.ts
tsx
// utils/trpc.ts
import { createReactQueryHooks } from '@trpc/react';
import type { AppRouter } from '../path/to/router.ts';
export const trpc = createReactQueryHooks<AppRouter>();
// => { useQuery: ..., useMutation: ...}

3. tRPCプロバイダーの追加

App.tsx内で設定します

App.tsx
tsx
import React, { useState } from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';
import { trpc } from './utils/trpc';
export function App() {
const [queryClient] = useState(() => new QueryClient());
const [trpcClient] = useState(() =>
trpc.createClient({
url: 'http://localhost:5000/trpc',
// optional
headers() {
return {
authorization: getAuthCookie(),
};
},
}),
);
return (
<trpc.Provider client={trpcClient} queryClient={queryClient}>
<QueryClientProvider client={queryClient}>
{/* Your app here */}
</QueryClientProvider>
</trpc.Provider>
);
}
App.tsx
tsx
import React, { useState } from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';
import { trpc } from './utils/trpc';
export function App() {
const [queryClient] = useState(() => new QueryClient());
const [trpcClient] = useState(() =>
trpc.createClient({
url: 'http://localhost:5000/trpc',
// optional
headers() {
return {
authorization: getAuthCookie(),
};
},
}),
);
return (
<trpc.Provider client={trpcClient} queryClient={queryClient}>
<QueryClientProvider client={queryClient}>
{/* Your app here */}
</QueryClientProvider>
</trpc.Provider>
);
}

4. データの取得

pages/IndexPage.tsx
tsx
import { trpc } from '../utils/trpc';
export default function IndexPage() {
const hello = trpc.useQuery(['hello', { text: 'client' }]);
if (!hello.data) return <div>Loading...</div>;
return (
<div>
<p>{hello.data.greeting}</p>
</div>
);
}
pages/IndexPage.tsx
tsx
import { trpc } from '../utils/trpc';
export default function IndexPage() {
const hello = trpc.useQuery(['hello', { text: 'client' }]);
if (!hello.data) return <div>Loading...</div>;
return (
<div>
<p>{hello.data.greeting}</p>
</div>
);
}