TanStack Router v1 快速入门:构建类型安全的 React 路由

本篇完整指南将带您全面了解如何使用全新稳定发布的 TanStack Router v1,在您的 React 应用中构建完全类型定义安全、基于文件的现代化路由系统。无论是从全链路类型安全的链接生成、内置的强大数据加载与流式渲染支持,还是利用搜索参数作为状态管理和复杂的嵌套布局组合,它都能带给您前所未有的开发体验提升。

Alex Chen
Alex Chen
June 8, 20268 min read
其他语言:Deutsch

TanStack Router v1 现已稳定发布,它为 React 应用的路由管理带来了一种截然不同的方法。与传统路由器不同,TanStack Router 将路由视为一等 TypeScript 公民——为您提供从路由定义一直到链接生成的端到端类型安全。

为什么选择 TanStack Router?

在深入了解配置之前,我们先来看看 TanStack Router 创建的初衷。它主要解决以下核心问题:

  • 类型安全的链接 — <Link to="/blog/$slug" params={{ slug: 'hello' }}> 实现了完整的类型约束
  • 内置数据加载 — 支持 Suspense 和流式渲染的路由加载器
  • 搜索参数作为状态 — 经过校验且类型安全的 URL 搜索参数
  • 嵌套布局 — 利用嵌套的路由树组合复杂的用户界面

安装

bash
pnpm add @tanstack/react-router
pnpm add -D @tanstack/router-plugin @tanstack/router-devtools

基于文件的路由配置

在您的 Vite 配置文件中添加该路由插件:

ts
// vite.config.ts
import { tanstackRouter } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [
    tanstackRouter({ autoCodeSplitting: true }),
    react(),
  ],
})

创建您的第一个路由

创建 src/routes/index.tsx 文件:

tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/')({
  component: HomePage,
})

function HomePage() {
  return <h1>Welcome to my app</h1>
}

类型安全的导航

当您在不同路由之间进行导航时,它的真正威力才会显现出来:

tsx
import { Link, useNavigate } from '@tanstack/react-router'

// 完全类型安全 —— TypeScript 会捕获无效的路由
function NavBar() {
  const navigate = useNavigate()

  return (
    <nav>
      <Link to="/" className="...">Home</Link>
      <Link to="/blog/$slug" params={{ slug: 'my-post' }}>Blog</Link>
      <button onClick={() => navigate({ to: '/dashboard' })}>
        Dashboard
      </button>
    </nav>
  )
}

路由加载器

TanStack Router 提供了一等公民级别的路由层数据加载支持:

tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/users/$userId')({
  loader: async ({ params }) => {
    const user = await fetchUser(params.userId)
    return { user }
  },
  component: UserPage,
})

function UserPage() {
  const { user } = Route.useLoaderData()
  return <div>{user.name}</div>
}

搜索参数

类型安全的搜索参数是 TanStack Router 最强大的特性之一:

tsx
import { createFileRoute } from '@tanstack/react-router'
import { z } from 'zod'

const searchSchema = z.object({
  page: z.number().default(1),
  filter: z.string().optional(),
})

export const Route = createFileRoute('/products')({
  validateSearch: searchSchema,
  component: ProductsPage,
})

function ProductsPage() {
  const { page, filter } = Route.useSearch()
  // page 的类型被推断为 number,filter 的类型为 string | undefined
  return <ProductGrid page={page} filter={filter} />
}

嵌套布局

使用布局路由来构建复杂的 UI 组合:

src/routes/
  __root.tsx          ← 根布局(页眉、页脚)
  dashboard.tsx       ← 仪表盘布局(侧边栏)
  dashboard/
    index.tsx         ← /dashboard
    analytics.tsx     ← /dashboard/analytics
    settings.tsx      ← /dashboard/settings

每个布局文件通过渲染 <Outlet /> 来显示其子节点:

tsx
// dashboard.tsx
import { createFileRoute, Outlet } from '@tanstack/react-router'

export const Route = createFileRoute('/dashboard')({
  component: DashboardLayout,
})

function DashboardLayout() {
  return (
    <div className="flex">
      <Sidebar />
      <main className="flex-1">
        <Outlet />
      </main>
    </div>
  )
}

后续探索

现在您已经掌握了基本用法,接下来可以探索:

  • 上下文 (Context) — 在父子路由之间共享数据
  • 待处理组件 (Pending components) — 在导航期间显示加载状态
  • 错误边界 (Error boundaries) — 优雅地处理路由错误
  • 路由守卫 (Route guards) — 重定向未授权用户

TanStack Router 将类型安全、基于文件的约定规范与强大的数据加载能力融为一体,使其成为任何 React 应用不可多得的绝佳基础。