
기존 React 프로젝트에서 라우팅은 React Router DOM을 기본적으로 사용했었지만, 이번 프로젝트에서부턴 TanStack Router를 도입하였다.
1) React Router DOM의 코드 라우팅 방식의 단점
React Router DOM은 라우트를 코드로 직접 선언하는 방식이다.
해당 방식에서 느낀 단점은 다음과 같다:
이 단점을 보완한 방식이 바로 TanStack Router이다.
TanStack Router는 파일 기반 라우팅을 지원한다.
파일을 만들면 라우트가 자동 등록되고, 파일 구조가 그대로 URL 구조가 된다.
⇒ 너무 편하다!
위와 같은 이유로, tanstack router를 실제 프로젝트에 도입하게 되었다.
해당 프로젝트는 react + vite + pnpm 을 기반으로 진행합니다.
차이점이 있을 경우 아래 내용과 다를 수 있으니 참고해주세요!
먼저, 다음의 내용을 터미널에 입력해 프로젝트 내에 tanstack-router 패키지를 설치한다.
pnpm add @tanstack/react-router
pnpm add -D @tanstack/router-plugin @tanstack/router-devtools
설치를 마쳤다면, vite.config.ts 파일을 열어서 해당 라이브러리를 import 한 후, plugins에 추가해주자.
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
import { TanStackRouterVite } from '@tanstack/router-plugin/vite'
export default defineConfig({
plugins: [
TanStackRouterVite(), // 반드시 react()보다 앞에 위치
react(),
tailwindcss(),
],
})
src/ 폴더 내부에 routes 폴더를 만든 뒤 __root.tsx 를 생성한다.
import { createRootRoute, Outlet } from '@tanstack/react-router'
export const Route = createRootRoute({
component: () => <Outlet />,
})
생성을 마쳤다면, pnpm dev으로 개발 서버를 실행해주자.
tanstack이 src/routeTree.gen.ts파일을 자동으로 생성해준다!
__root.tsx파일 없이 실행할 경우 tanstack이 인식하지 못해 생성해주지 않는다 꼭 전부 설정한 후 진행하자.
routeTree.gen.ts 파일이 제대로 생성되었다면,
라우터 설정을 위한 router.ts 파일을 생성한다.
import { createRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
export const router = createRouter({ routeTree })
declare module '@tanstack/react-router' {
interface Register {
router: typeof router
}
}
프로젝트 규모가 작은 경우 main.tsx 파일 내부에 설정해도 괜찮다!
마지막으로 main.tsx 파일을 설정해주면 초기 세팅은 마무리된다.
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { RouterProvider } from '@tanstack/react-router'
import { router } from './router'
import './index.css'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<RouterProvider router={router} />
</StrictMode>,
)
App.tsx 는 TanStack Router 사용 시 불필요하니 삭제해주자.routeTree.gen.ts 는 자동 생성되는 파일이므로, 직접 수정하면 오류가 날 수 있다!tanstack router는 파일 기반 라우팅이다.
파일/폴더 구조가 그대로 URL 구조가 되는 방식이다.
- Next.js 구조와 유사하다고 생각하면 된다.
페이지 하나만 있을 땐, 원하는 URL 이름으로 파일 명을 생성해주면 된다.
src/routes/
├── experience.tsx # /experience
└── contact.tsx # /contact
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/experience')({
component: () => <div>경력 페이지</div>,
})
이 방식은 중첩 라우트가 필요하지만, 공통 레이아웃이 없을 때 사용한다
src/routes/
└── projects/
├── index.tsx # /projects
└── $id.tsx # /projects/:id
// src/routes/projects/$id.tsx
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/projects/$id')({
component: () => <div>프로젝트 상세</div>,
})
하위 페이지들이 공통 레이아웃을 공유할 때 사용한다.
route.tsx가 레이아웃을 담당하고 <Outlet />으로 하위 페이지를 렌더링한다.
src/routes/
└── projects/
├── route.tsx # /projects 레이아웃 (헤더, 컨테이너 등 공통 UI)
├── index.tsx # /projects
└── $id.tsx # /projects/:id
// src/routes/projects/route.tsx
import { createFileRoute, Outlet } from '@tanstack/react-router'
export const Route = createFileRoute('/projects')({
component: () => (
<div>
{/* 공통 레이아웃 */}
<Outlet />
</div>
),
})
| 상황 | 패턴 |
|---|---|
| 페이지 하나, 중첩 없음 | 단일 파일 |
| 중첩 라우트, 공통 레이아웃 없음 | 폴더 구조 |
| 중첩 라우트 + 공통 레이아웃 필요 | route.tsx 패턴 |
pnpm dev 실행 중이면 파일 저장 즉시 routeTree.gen.ts 자동 업데이트$ 접두사는 동적 파라미터 — $id.tsx → URL에서 :id에 해당route.tsx는 반드시 <Outlet />을 포함해야 하위 페이지가 렌더링됨