TanStack Router 入門:型安全なルーティングの基本
TanStack Routerとは
TanStack RouterはReact向けの型安全なルーティングライブラリです。URLパラメータやクエリパラメータまでTypeScriptの型が効き、遷移先のパスも補完されます。React Router v6と比べてTypeScriptとの統合が強力です。
React Router v6との主な違い
| React Router v6 | TanStack Router | |
|---|---|---|
| 型安全 | △(パラメータは手動で型定義) | ◎(ルート定義から型が自動で付く) |
| ファイルベースルーティング | なし | あり(オプション) |
| 検索パラメータ | 手動でパース | スキーマで定義して型付き |
| ローダー(データフェッチ) | なし | ルートに直接定義可 |
インストール
npm install @tanstack/react-router
コードベースルーティング(基本)
ルートを定義する
// src/router.tsx import { createRouter, createRoute, createRootRoute } from '@tanstack/react-router' import Home from './pages/Home' import About from './pages/About' const rootRoute = createRootRoute({ component: () => ( <div> <nav> <Link to="/">ホーム</Link> <Link to="/about">About</Link> </nav> <Outlet /> </div> ), }) const homeRoute = createRoute({ getParentRoute: () => rootRoute, path: '/', component: Home, }) const aboutRoute = createRoute({ getParentRoute: () => rootRoute, path: '/about', component: About, }) const routeTree = rootRoute.addChildren([homeRoute, aboutRoute]) export const router = createRouter({ routeTree }) // TypeScriptの型登録 declare module '@tanstack/react-router' { interface Register { router: typeof router } }
Providerで囲む
// src/main.tsx import { RouterProvider } from '@tanstack/react-router' import { router } from './router' createRoot(document.getElementById('root')!).render( <RouterProvider router={router} /> )
Linkで遷移する
to の値が補完されます。存在しないパスはTypeScriptエラーになります。
import { Link } from '@tanstack/react-router' function Nav() { return ( <nav> <Link to="/">ホーム</Link> <Link to="/about">About</Link> </nav> ) }
URLパラメータ
const userRoute = createRoute({ getParentRoute: () => rootRoute, path: '/users/$id', // $id がパラメータ component: UserDetail, }) function UserDetail() { const { id } = userRoute.useParams() // 型が付いている return <p>ユーザーID: {id}</p> }
検索パラメータ(型安全)
import { z } from 'zod' const searchRoute = createRoute({ getParentRoute: () => rootRoute, path: '/search', validateSearch: z.object({ q: z.string().default(''), page: z.number().default(1), }), component: SearchPage, }) function SearchPage() { const { q, page } = searchRoute.useSearch() // q: string, page: number が確定 return <p>{q} - {page}ページ目</p> }
useNavigateでプログラム遷移
import { useNavigate } from '@tanstack/react-router' function LoginForm() { const navigate = useNavigate() const handleLogin = async () => { await login() navigate({ to: '/dashboard' }) // パスが補完される } return <button onClick={handleLogin}>ログイン</button> }
ローダーでデータを事前取得する
ルートに loader を定義すると、コンポーネントが描画される前にデータを取得できます。
const userRoute = createRoute({ getParentRoute: () => rootRoute, path: '/users/$id', loader: async ({ params }) => { const user = await fetch(`/api/users/${params.id}`).then((r) => r.json()) return { user } }, component: UserDetail, }) function UserDetail() { const { user } = userRoute.useLoaderData() // 型が付いている return <p>{user.name}</p> }
まとめ
| API | 用途 |
|---|---|
createRootRoute |
ルートの親ルートを作成 |
createRoute |
各ルートを定義 |
RouterProvider |
ルーターのProvider |
Link |
型安全なリンク |
useNavigate |
プログラム遷移 |
useParams |
URLパラメータ(型付き) |
useSearch |
検索パラメータ(型付き) |
loader |
ルートのデータ事前取得 |
- TypeScriptプロジェクトではReact Routerより型安全に書ける
- 検索パラメータをスキーマで定義できるのが強み
- ファイルベースルーティングも使えるが、コードベースでも十分シンプル
Reactのプロジェクト作成から始める場合は「React + Vite でプロジェクト作成」を参照してください。
React Router v6の基本は「React Router v6 入門」を参照してください。