TanStack Start 中文文档
服务器与执行

路由

TanStack Start 建立在 TanStack Router 之上,因此 TanStack Router 的所有特性对你都可用。

注意

我们强烈建议阅读 TanStack Router 文档 来了解 TanStack Router 的特性和能力。本页内容更偏向于提供 TanStack Router 及其在 Start 中工作方式的高层概览。

路由器(Router)

router.tsx 文件决定了 Start 中使用的 TanStack Router 的行为。它位于项目的 src 目录下。

src/
├── router.tsx

在这里,你可以配置从默认的预加载功能缓存过期策略的一切。

// src/router.tsx
import { createRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'

// You must export a getRouter function that
// returns a new router instance each time
export function getRouter() {
  const router = createRouter({
    routeTree,
    scrollRestoration: true,
  })

  return router
}

译者注:为什么 getRouter 每次要返回新实例?

Start 是服务端渲染框架,而 React 的服务端渲染要求每次请求都有独立的、干净的路由器状态。如果复用同一个路由器实例,不同用户/请求之间的状态(比如当前 URL、加载中的缓存)就会互相污染。所以约定是用 getRouter() 工厂函数在每次请求时创建一个全新的路由器实例。

基于文件的路由(File-Based Routing)

Start 使用 TanStack Router 的基于文件的路由方式,以确保正确的代码分割(code-splitting)和高级类型安全。

你可以在 src/routes 目录中找到你的路由。

src/
├── routes <-- This is where you put your routes
│   ├── __root.tsx
│   ├── index.tsx
│   ├── about.tsx
│   ├── posts.tsx
│   ├── posts/$postId.tsx

根路由(Root Route)

根路由是整个路由树中最顶层的路由,它把其他所有路由都作为子级封装起来。它位于 src/routes/__root.tsx 文件中,且必须命名为 __root.tsx

src/
├── routes
│   ├── __root.tsx <-- The root route
  • 它没有路径,并且总是被匹配
  • 它的 component 总是被渲染
  • 这里是渲染文档外壳(document shell)的地方,比如 <html><body>
  • 正因为它总是被渲染,它是构建应用外壳、处理全局逻辑的完美场所
// src/routes/__root.tsx
import {
  Outlet,
  createRootRoute,
  HeadContent,
  Scripts,
} from '@tanstack/react-router'
import type { ReactNode } from 'react'

export const Route = createRootRoute({
  head: () => ({
    meta: [
      {
        charSet: 'utf-8',
      },
      {
        name: 'viewport',
        content: 'width=device-width, initial-scale=1',
      },
      {
        title: 'TanStack Start Starter',
      },
    ],
  }),
  component: RootComponent,
})

function RootComponent() {
  return (
    <RootDocument>
      <Outlet />
    </RootDocument>
  )
}

function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
  return (
    <html>
      <head>
        <HeadContent />
      </head>
      <body>
        {children}
        <Scripts />
      </body>
    </html>
  )
}

注意 <body> 标签底部的 Scripts 组件。它用于加载应用所需的全部客户端 JavaScript,为保证功能正常,必须始终包含它

HeadContent 组件

HeadContent 组件用于渲染文档的 <head><title>、meta、link 以及头部相关的 script 标签。

它应该渲染在根路由布局的 <head> 标签中。

Outlet 组件

Outlet 组件用于渲染下一个可能匹配的子路由。<Outlet /> 不接收任何 props,可以渲染在路由组件树中的任何位置。如果没有匹配的子路由,<Outlet /> 会渲染 null

Scripts 组件

Scripts 组件用于渲染文档的 body 脚本。

它应该渲染在根路由布局的 <body> 标签中。

路由树生成(Route Tree Generation)

你可能会注意到项目中有一个 routeTree.gen.ts 文件。

src/
├── routeTree.gen.ts <-- The generated route tree file

这个文件会在你运行 TanStack Start 时(通过 npm run devnpm run start)自动生成。它包含了生成的路由树,以及一批让 TanStack Start 的类型安全既快速又完整的 TS 工具函数。

嵌套路由(Nested Routing)

TanStack Router 使用嵌套路由,把 URL 匹配到要渲染的正确组件树。

例如,给定以下路由:

routes/
├── __root.tsx <-- Renders the <Root> component
├── posts.tsx <-- Renders the <Posts> component
├── posts.$postId.tsx <-- Renders the <Post> component

以及 URL:/posts/123

组件树会是这样的:

<Root>
  <Posts>
    <Post />
  </Posts>
</Root>

路由类型

项目中可以创建几种不同类型的路由。

  • 索引路由(Index Routes)——当 URL 与路由路径完全一致时被匹配
  • 动态/通配/全匹配路由(Dynamic/Wildcard/Splat Routes)——把 URL 路径的一部分或全部动态捕获到变量中,供应用使用

此外,还有几种工具型路由类型,用于分组和整理你的路由:

  • 无路径布局路由(Pathless Layout Routes)——对一组路由应用布局或逻辑,而不把它们嵌套在某个路径下
  • 非嵌套路由(Non-Nested Routes)——让路由脱离父级嵌套,渲染自己的组件树
  • 分组路由(Grouped Routes)——仅仅为了组织方便,在目录中把路由归组,而不影响路径层级

路由树配置

路由树在 src/routes 目录中配置。

创建文件路由

要创建路由,新建一个与你想创建的路由路径对应的文件即可。例如:

路径文件名类型
/index.tsx索引路由
/aboutabout.tsx静态路由
posts.tsx「布局」路由
/posts/posts/index.tsx索引路由
/posts/:postIdposts/$postId.tsx动态路由
/rest/*rest/$.tsx通配路由

定义路由

要定义路由,使用 createFileRoute 函数把路由导出为 Route 变量。

例如,要处理 /posts/:postId 路由,你需要在这里创建一个名为 posts/$postId.tsx 的文件:

src/
├── routes
│   ├── posts/$postId.tsx

然后像这样定义路由:

// src/routes/posts/$postId.tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/posts/$postId')({
  component: PostComponent,
})

注意

传给 createFileRoute 的路径字符串由 TanStack Router 的打包插件(Bundler Plugin)或 Router CLI 自动为你写入和维护。 所以,当你创建新路由、移动路由或重命名路由时,路径会自动为你更新。

这只是个「起点」

这里只是关于如何用 TanStack Router 配置路由的高层概览。更详细的内容,请参考 TanStack Router 文档

On this page