본문 바로가기
버전: 11.x

TanStack React Query

비공식 베타 번역

이 페이지는 PageTurner AI로 번역되었습니다(베타). 프로젝트 공식 승인을 받지 않았습니다. 오류를 발견하셨나요? 문제 신고 →

Compared to our classic React Query Integration this client is simpler and more TanStack Query-native, providing factories for common TanStack React Query interfaces like QueryKeys, QueryOptions, and MutationOptions. We think it's the future and recommend using this over the classic client, read the announcement post for more information about this change.

tRPC.io 홈페이지에서 이 통합을 직접 체험해 볼 수 있습니다: https://trpc.io/?try=minimal-react#try-it-out

❓ Do I have to use an integration?

No! The integration is fully optional. You can use @tanstack/react-query using just a vanilla tRPC client, although then you'll have to manually manage query keys and do not get the same level of DX as when using the integration package.

utils/trpc.ts
ts
export const trpc = createTRPCClient<AppRouter>({
links: [httpBatchLink({ url: 'YOUR_API_URL' })],
});
utils/trpc.ts
ts
export const trpc = createTRPCClient<AppRouter>({
links: [httpBatchLink({ url: 'YOUR_API_URL' })],
});
components/PostList.tsx
tsx
function PostList() {
const { data } = useQuery({
queryKey: ['posts'],
queryFn: () => trpc.post.list.query(),
});
data; // Post[]
// ...
}
components/PostList.tsx
tsx
function PostList() {
const { data } = useQuery({
queryKey: ['posts'],
queryFn: () => trpc.post.list.query(),
});
data; // Post[]
// ...
}

설정

1. 의존성 설치

다음 의존성들을 설치해야 합니다

npm install @trpc/server @trpc/client @trpc/tanstack-react-query @tanstack/react-query

2. AppRouter 가져오기

비공식 베타 번역

이 페이지는 PageTurner AI로 번역되었습니다(베타). 프로젝트 공식 승인을 받지 않았습니다. 오류를 발견하셨나요? 문제 신고 →

클라이언트 애플리케이션에 AppRouter 타입을 가져옵니다. 이 타입은 전체 API의 구조를 담고 있습니다.

utils/trpc.ts
ts
import type { AppRouter } from '../server/router';
utils/trpc.ts
ts
import type { AppRouter } from '../server/router';

import type을 사용하면 컴파일 시점에 참조가 제거되어 실수로 서버 측 코드를 클라이언트로 가져오는 것을 방지할 수 있습니다. 자세한 내용은 TypeScript 문서를 참조하세요.

3a. tRPC 컨텍스트 프로바이더 설정

Next.js와 같은 풀스택 프레임워크에서 서버 사이드 렌더링을 사용할 때와 같이 React 컨텍스트에 의존하는 경우, 사용자들이 동일한 캐시를 공유하지 않도록 각 요청마다 새로운 QueryClient를 생성하는 것이 중요합니다. createTRPCContext를 사용해 AppRouter 타입 시그니처로부터 타입 안전한 컨텍스트 프로바이더와 컨슈머 세트를 생성할 수 있습니다.

utils/trpc.ts
tsx
import { createTRPCContext } from '@trpc/tanstack-react-query';
import type { AppRouter } from '../server/router';
 
export const { TRPCProvider, useTRPC, useTRPCClient } = createTRPCContext<AppRouter>();
utils/trpc.ts
tsx
import { createTRPCContext } from '@trpc/tanstack-react-query';
import type { AppRouter } from '../server/router';
 
export const { TRPCProvider, useTRPC, useTRPCClient } = createTRPCContext<AppRouter>();

이후 아래와 같이 tRPC 클라이언트를 생성하고 애플리케이션을 TRPCProvider로 감싸세요. 또한 React Query를 설정하고 연결해야 하며, 해당 문서에서 더 자세히 설명합니다.

애플리케이션에서 이미 React Query를 사용 중이라면 기존의 QueryClientQueryClientProvider반드시 재사용해야 합니다. QueryClient 초기화에 대한 자세한 내용은 React Query 문서에서 확인할 수 있습니다.

components/App.tsx
tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { createTRPCClient, httpBatchLink } from '@trpc/client';
import { useState } from 'react';
import { TRPCProvider } from './utils/trpc';
function makeQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
// With SSR, we usually want to set some default staleTime
// above 0 to avoid refetching immediately on the client
staleTime: 60 * 1000,
},
},
});
}
let browserQueryClient: QueryClient | undefined = undefined;
function getQueryClient() {
if (typeof window === 'undefined') {
// Server: always make a new query client
return makeQueryClient();
} else {
// Browser: make a new query client if we don't already have one
// This is very important, so we don't re-make a new client if React
// suspends during the initial render. This may not be needed if we
// have a suspense boundary BELOW the creation of the query client
if (!browserQueryClient) browserQueryClient = makeQueryClient();
return browserQueryClient;
}
}
export function App() {
const queryClient = getQueryClient();
const [trpcClient] = useState(() =>
createTRPCClient<AppRouter>({
links: [
httpBatchLink({
url: 'http://localhost:2022',
}),
],
}),
);
return (
<QueryClientProvider client={queryClient}>
<TRPCProvider trpcClient={trpcClient} queryClient={queryClient}>
{/* Your app here */}
</TRPCProvider>
</QueryClientProvider>
);
}
components/App.tsx
tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { createTRPCClient, httpBatchLink } from '@trpc/client';
import { useState } from 'react';
import { TRPCProvider } from './utils/trpc';
function makeQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
// With SSR, we usually want to set some default staleTime
// above 0 to avoid refetching immediately on the client
staleTime: 60 * 1000,
},
},
});
}
let browserQueryClient: QueryClient | undefined = undefined;
function getQueryClient() {
if (typeof window === 'undefined') {
// Server: always make a new query client
return makeQueryClient();
} else {
// Browser: make a new query client if we don't already have one
// This is very important, so we don't re-make a new client if React
// suspends during the initial render. This may not be needed if we
// have a suspense boundary BELOW the creation of the query client
if (!browserQueryClient) browserQueryClient = makeQueryClient();
return browserQueryClient;
}
}
export function App() {
const queryClient = getQueryClient();
const [trpcClient] = useState(() =>
createTRPCClient<AppRouter>({
links: [
httpBatchLink({
url: 'http://localhost:2022',
}),
],
}),
);
return (
<QueryClientProvider client={queryClient}>
<TRPCProvider trpcClient={trpcClient} queryClient={queryClient}>
{/* Your app here */}
</TRPCProvider>
</QueryClientProvider>
);
}

3b. 쿼리/뮤테이션 키 접두사 설정 사용

모든 쿼리와 뮤테이션에 특정 키를 접두사로 추가하려면, 설정 및 사용 예시는 쿼리 키 접두사를 참조하세요.

3c. React 컨텍스트 없이 설정

Vite 같은 도구를 사용해 클라이언트 사이드 렌더링만으로 SPA를 구축할 때는 React 컨텍스트 외부에 QueryClient와 tRPC 클라이언트를 싱글톤으로 생성할 수 있습니다.

utils/trpc.ts
ts
import { QueryClient } from '@tanstack/react-query';
import { createTRPCClient, httpBatchLink } from '@trpc/client';
import { createTRPCOptionsProxy } from '@trpc/tanstack-react-query';
import type { AppRouter } from '../server/router';
export const queryClient = new QueryClient();
const trpcClient = createTRPCClient<AppRouter>({
links: [httpBatchLink({ url: 'http://localhost:2022' })],
});
export const trpc = createTRPCOptionsProxy<AppRouter>({
client: trpcClient,
queryClient,
});
utils/trpc.ts
ts
import { QueryClient } from '@tanstack/react-query';
import { createTRPCClient, httpBatchLink } from '@trpc/client';
import { createTRPCOptionsProxy } from '@trpc/tanstack-react-query';
import type { AppRouter } from '../server/router';
export const queryClient = new QueryClient();
const trpcClient = createTRPCClient<AppRouter>({
links: [httpBatchLink({ url: 'http://localhost:2022' })],
});
export const trpc = createTRPCOptionsProxy<AppRouter>({
client: trpcClient,
queryClient,
});
components/App.tsx
tsx
import { QueryClientProvider } from '@tanstack/react-query';
import React from 'react';
import { queryClient } from './utils/trpc';
export function App() {
return (
<QueryClientProvider client={queryClient}>
{/* Your app here */}
</QueryClientProvider>
);
}
components/App.tsx
tsx
import { QueryClientProvider } from '@tanstack/react-query';
import React from 'react';
import { queryClient } from './utils/trpc';
export function App() {
return (
<QueryClientProvider client={queryClient}>
{/* Your app here */}
</QueryClientProvider>
);
}

4. 데이터 가져오기

이제 tRPC React Query 통합을 사용해 API에 대한 쿼리 및 뮤테이션을 호출할 수 있습니다.

components/user-list.tsx
tsx
import { useMutation, useQuery } from '@tanstack/react-query';
import { useTRPC } from '../utils/trpc';
export default function UserList() {
const trpc = useTRPC(); // use `import { trpc } from './utils/trpc'` if you're using the singleton pattern
const userQuery = useQuery(trpc.getUser.queryOptions({ id: 'id_bilbo' }));
const userCreator = useMutation(trpc.createUser.mutationOptions());
return (
<div>
<p>{userQuery.data?.name}</p>
<button onClick={() => userCreator.mutate({ name: 'Frodo' })}>
Create Frodo
</button>
</div>
);
}
components/user-list.tsx
tsx
import { useMutation, useQuery } from '@tanstack/react-query';
import { useTRPC } from '../utils/trpc';
export default function UserList() {
const trpc = useTRPC(); // use `import { trpc } from './utils/trpc'` if you're using the singleton pattern
const userQuery = useQuery(trpc.getUser.queryOptions({ id: 'id_bilbo' }));
const userCreator = useMutation(trpc.createUser.mutationOptions());
return (
<div>
<p>{userQuery.data?.name}</p>
<button onClick={() => userCreator.mutate({ name: 'Frodo' })}>
Create Frodo
</button>
</div>
);
}