TanStack React Query
기존 React Query 통합과 비교하면 이 클라이언트는 더 단순하고 TanStack Query 방식에 가깝습니다. QueryKeys, QueryOptions, MutationOptions 같은 일반적인 TanStack React Query 인터페이스의 팩토리도 제공합니다. 기존 클라이언트보다 이 클라이언트를 권장하며, 자세한 내용은 발표 게시물에서 확인할 수 있습니다.
tRPC.io 홈페이지에서 이 통합을 직접 사용해 볼 수 있습니다: https://trpc.io/?try=minimal-react#try-it-out
❓ 통합을 반드시 사용해야 하나요?
아니요! 통합은 완전히 선택 사항입니다. 바닐라 tRPC 클라이언트만 사용하여 @tanstack/react-query를 사용할 수 있지만, 이 경우 쿼리 키를 수동으로 관리해야 하며 통합 패키지를 사용할 때와 동일한 수준의 DX를 제공받지 못합니다.
utils/trpc.tstsimport {createTRPCClient ,httpBatchLink } from '@trpc/client';import type {AppRouter } from '../server/router';export consttrpc =createTRPCClient <AppRouter >({links : [httpBatchLink ({url : 'YOUR_API_URL' })],});
utils/trpc.tstsimport {createTRPCClient ,httpBatchLink } from '@trpc/client';import type {AppRouter } from '../server/router';export consttrpc =createTRPCClient <AppRouter >({links : [httpBatchLink ({url : 'YOUR_API_URL' })],});
components/PostList.tsxtsximport {useQuery } from '@tanstack/react-query';import {trpc } from './utils/trpc';functionPostList () {const {data } =useQuery ({queryKey : ['posts'] asconst ,queryFn : () =>trpc .post .list .query (),});data ; // Post[]// ...}
components/PostList.tsxtsximport {useQuery } from '@tanstack/react-query';import {trpc } from './utils/trpc';functionPostList () {const {data } =useQuery ({queryKey : ['posts'] asconst ,queryFn : () =>trpc .post .list .query (),});data ; // Post[]// ...}
설정
1. 의존성 설치
다음 의존성을 설치해야 합니다
- npm
- yarn
- pnpm
- bun
- deno
npm install @trpc/server @trpc/client @trpc/tanstack-react-query @tanstack/react-query
yarn add @trpc/server @trpc/client @trpc/tanstack-react-query @tanstack/react-query
pnpm add @trpc/server @trpc/client @trpc/tanstack-react-query @tanstack/react-query
bun add @trpc/server @trpc/client @trpc/tanstack-react-query @tanstack/react-query
deno add npm:@trpc/server npm:@trpc/client npm:@trpc/tanstack-react-query npm:@tanstack/react-query
AI 코딩 에이전트를 사용하는 경우, 더 나은 코드 생성을 위해 tRPC 스킬을 설치하세요:
bashnpx @tanstack/intent@latest install
bashnpx @tanstack/intent@latest install
2. AppRouter 가져오기
AppRouter 타입을 클라이언트 애플리케이션에 가져옵니다. 이 타입은 전체 API의 구조를 포함합니다.
utils/trpc.tstsimport type { AppRouter } from '../server/router';
utils/trpc.tstsimport type { AppRouter } from '../server/router';
import type를 사용하면 참조가 컴파일 타임에 제거되므로, 서버 측 코드가 클라이언트에 의도치 않게 가져와지는 것을 방지할 수 있습니다. 자세한 내용은 TypeScript 문서를 참조하세요.
3a. tRPC 컨텍스트 프로바이더 설정
Next.js와 같은 풀스택 프레임워크에서 서버 사이드 렌더링을 사용하는 경우와 같이 React 컨텍스트에 의존하는 경우, 사용자가 동일한 캐시를 공유하지 않도록 각 요청마다 새로운 QueryClient를 생성하는 것이 중요합니다. createTRPCContext를 사용하여 AppRouter 타입 시그니처에서 타입 안전한 컨텍스트 프로바이더와 컨슈머 세트를 생성할 수 있습니다.
utils/trpc.tstsximport {createTR PCContext } from '@trpc/tanstack-react-query';importtype { AppRouter } from '../server/router'; export const { TRPCProvider, useTRPC, useTRPCClient } = createTRPCContext<AppRouter>();
utils/trpc.tstsximport {createTR PCContext } from '@trpc/tanstack-react-query';importtype { AppRouter } from '../server/router'; export const { TRPCProvider, useTRPC, useTRPCClient } = createTRPCContext<AppRouter>();
그런 다음, 아래에 표시된 것처럼 tRPC 클라이언트를 생성하고 애플리케이션을 TRPCProvider로 감싸야 합니다. 또한 더 자세히 문서화된 React Query를 설정하고 연결해야 합니다.
애플리케이션에서 이미 React Query를 사용하는 경우, 이미 가지고 있는 QueryClient와 QueryClientProvider를 재사용하는 것이 좋습니다. QueryClient 초기화에 대한 자세한 내용은 React Query 문서에서 확인할 수 있습니다.
components/App.tsxtsximport {QueryCli ent, QueryClientProvider } from '@tanstack/react-query';import{ createTRPCClient, httpBatchLink } from '@trpc/client'; import{ useState } from 'react'; import type { AppRouter } from '../server/router';import{ TRPCProvider } from '../utils/trpc'; functionmakeQueryClient() { 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 clientreturn 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 clientif (!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}>{null /* Your app here */}</TRPCProvider></QueryClientProvider>);}
components/App.tsxtsximport {QueryCli ent, QueryClientProvider } from '@tanstack/react-query';import{ createTRPCClient, httpBatchLink } from '@trpc/client'; import{ useState } from 'react'; import type { AppRouter } from '../server/router';import{ TRPCProvider } from '../utils/trpc'; functionmakeQueryClient() { 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 clientreturn 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 clientif (!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}>{null /* Your app here */}</TRPCProvider></QueryClientProvider>);}
3b. 쿼리/뮤테이션 키 접두사 사용으로 설정
모든 쿼리와 뮤테이션에 특정 키를 접두사로 추가하려면 설정 및 사용 예시를 위해 쿼리 키 접두사를 참조하세요.
3c. React 컨텍스트 없이 설정
Vite와 같은 도구를 사용하여 클라이언트 사이드 렌더링만 사용하는 SPA를 구축할 때, QueryClient와 tRPC 클라이언트를 React 컨텍스트 외부에서 싱글턴으로 생성할 수 있습니다.
utils/trpc.tstsimport {QueryCli ent } from '@tanstack/react-query';import{ createTRPCClient, httpBatchLink } from '@trpc/client'; import{ createTRPCOptionsProxy } from '@trpc/tanstack-react-query'; import type { AppRouter } from '../server/router';exportconst queryClient = new QueryClient (); const trpcClient = createTRPCClient<AppRouter>({links: [httpBatchLink({ url: 'http://localhost:2022' })], });export const trpc = createTRPCOptionsProxy<AppRouter>({client:trpcClient, queryClient,});
utils/trpc.tstsimport {QueryCli ent } from '@tanstack/react-query';import{ createTRPCClient, httpBatchLink } from '@trpc/client'; import{ createTRPCOptionsProxy } from '@trpc/tanstack-react-query'; import type { AppRouter } from '../server/router';exportconst queryClient = new QueryClient (); const trpcClient = createTRPCClient<AppRouter>({links: [httpBatchLink({ url: 'http://localhost:2022' })], });export const trpc = createTRPCOptionsProxy<AppRouter>({client: trpcClient, queryClient,});
components/App.tsxtsximport {QueryCli entProvider } from '@tanstack/react-query';import{ queryClient } from '../utils/trpc'; export function App() {return (<QueryClientProvider client= {queryClient}> {/* Your app here */} </QueryClientProvider>);}
components/App.tsxtsximport {QueryCli entProvider } from '@tanstack/react-query';import{ queryClient } from '../utils/trpc'; export function App() {return (<QueryClientProvider client= {queryClient}> {/* Your app here */} </QueryClientProvider>);}
4. 데이터 가져오기
이제 tRPC React Query 통합을 사용하여 API에서 쿼리와 뮤테이션을 호출할 수 있습니다.
components/user-list.tsxtsximport {useMutat ion, 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 constuserQuery = 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.tsxtsximport {useMutat ion, 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 constuserQuery = 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>);}