Usage with React
info
- If you're using Next.js, read the Usage with Next.js guide instead.
- In order to infer types from your Node.js backend you should have the frontend & backend in the same monorepo.
Add tRPC to existing React project
Server Side
1. Install dependencies
yarn add @trpc/server zod
- Zod: most examples use Zod for input validation and we highly recommended it, though it isn't required. You can use a validation library of your choice (Yup, Superstruct, io-ts, etc). In fact, any object containing a
parse
,create
orvalidateSync
method will work.
2. Enable strict mode
If you want to use Zod for input validation, make sure you have enabled strict mode in your tsconfig.json
:
// tsconfig.json
{
// ...
"compilerOptions": {
// ...
"strict": true
}
}
If strict mode is too much, at least enable strictNullChecks
:
// tsconfig.json
{
// ...
"compilerOptions": {
// ...
"strictNullChecks": true
}
}
3. Implement your appRouter
Follow the Quickstart and read the @trpc/server
docs for guidance on this. Once you have your API implemented and listening via HTTP, continue to the next step.
Client Side
tRPC works fine with Create React App!
1. Install dependencies
yarn add @trpc/client @trpc/server @trpc/react react-query@3
- @trpc/server: This is a peer dependency of
@trpc/client
so you have to install it again! - React Query: @trpc/react provides a thin wrapper over react-query. It is required as a peer dependency.
2. Create tRPC hooks
Create a set of strongly-typed React hooks from your AppRouter
type signature with createReactQueryHooks
.
utils/trpc.ts
// utils/trpc.ts
import { createReactQueryHooks } from '@trpc/react';
import type { AppRouter } from '../path/to/router.ts';
export const trpc = createReactQueryHooks<AppRouter>();
// => { useQuery: ..., useMutation: ...}
3. Add tRPC providers
In your App.tsx
App.tsx
import React from 'react';
import { 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. Fetch data
pages/IndexPage.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>
);
};