Tanstack Router 基础教程:快速掌握核心概念 – wiki基地


Tanstack Router 基础教程:快速掌握核心概念

路由是现代前端应用不可或缺的一部分,它负责管理应用程序的不同视图、处理URL、导航以及潜在的数据加载。在 React 生态系统中,React Router 是一个非常流行的选择。然而,随着前端应用变得越来越复杂,开发者对路由库提出了更高的要求,例如更好的类型安全、更优雅的数据加载机制、以及更优化的性能。

Tanstack Router (原名为 TanStack Router 或 React Location 的继任者) 应运而生,它由 Tanstack (开发 React Query, React Table 等知名库的团队) 打造,旨在提供一个更现代、更强大的路由解决方案。本篇文章将带你深入了解 Tanstack Router 的核心概念,帮助你快速上手并理解它的独特之处。

为什么选择 Tanstack Router?

在深入细节之前,我们先了解一下 Tanstack Router 的主要优势,它们也是促使开发者考虑使用它的关键因素:

  1. 强类型安全 (Type Safety First): 这是 Tanstack Router 的核心卖点之一。通过内置的类型生成工具,它能确保你的路由路径、参数 (params)、搜索参数 (search) 都是强类型的。这意味着你可以在编译时捕获许多常见的路由错误,而不是在运行时。例如,如果你尝试导航到一个不存在的路由,或者为一个需要参数的路由遗漏了参数,TypeScript 就会报错。
  2. 内置数据加载 (Built-in Data Loading): Tanstack Router 在路由层面提供了强大的数据加载能力 (loader 函数)。你可以在路由定义中直接指定该路由需要加载的数据。路由器会在渲染组件之前自动触发数据加载,并将加载到的数据传递给组件。这极大地简化了数据获取逻辑,避免了常见的“请求瀑布”问题,并能更好地处理加载中和错误状态。
  3. 基于路由树的结构 (Route Tree): Tanstack Router 推崇通过一个扁平的路由配置数组来定义一个嵌套的路由树结构。这种结构清晰地映射了 URL 路径和组件层级,使得大型应用的路由管理更加直观和易于维护。
  4. 优化的性能 (Optimized Performance): 凭借其数据加载策略和内部优化,Tanstack Router 能够提供流畅的导航体验。它可以在路由转换开始时就并行加载数据,而不是等到组件渲染后才开始加载。
  5. 框架无关 (Potentially Framework Agnostic): 虽然目前主要与 React 结合紧密,但作为 Tanstack 生态的一部分,其设计理念是尽量做到框架无关,未来可能会更好地支持 Vue, Svelte 等其他框架。

对于追求更好的开发体验、更高代码质量以及更优应用性能的开发者来说,Tanstack Router 是一个值得深入学习和尝试的选择。

前置条件

在开始学习 Tanstack Router 之前,你需要具备以下基础:

  • 对 React 及其组件生命周期有基本了解。
  • 熟悉 JavaScript (ES6+) 和 TypeScript (强烈推荐,因为 Tanstack Router 的类型安全是其核心优势)。
  • 了解 Node.js 和 npm/yarn/pnpm 等包管理器。
  • 已经搭建好一个 React 开发环境 (例如使用 Create React App, Vite, Next.js 等)。

本教程将主要使用 TypeScript 和 Vite 来演示。

快速上手:安装与基本配置

首先,我们需要在你的 React 项目中安装 Tanstack Router。

“`bash

使用 npm

npm install @tanstack/react-router @tanstack/router-core

使用 yarn

yarn add @tanstack/react-router @tanstack/router-core

使用 pnpm

pnpm add @tanstack/react-router @tanstack/router-core
“`

安装完成后,我们需要进行基本的路由器设置。这通常在你的应用入口文件 (如 src/main.tsxsrc/index.tsx) 中完成。

1. 创建路由模块

推荐在一个单独的文件中定义你的路由配置,例如 src/routeTree.ts。这将使你的应用入口文件保持整洁。

“`typescript
// src/routeTree.ts
import { createRootRoute, createRoute } from ‘@tanstack/react-router’
import App from ‘./App’ // 你的根组件,通常包含布局和 Outlet

// 1. 创建根路由
// 根路由是所有其他路由的父级。它通常不对应具体的 URL 路径,
// 而是作为整个应用布局的容器。它包含一个 Outlet,子路由会渲染到这里。
export const rootRoute = createRootRoute({
component: () => {
// 根组件,可以包含全局布局元素(如导航栏、页脚)和 Outlet
return (
<>

{/ 稍后我们将使用 Link 组件进行导航 /}
首页
关于
文章

{/ Outlet 是子路由组件渲染的地方 /}


)
},
})

// 2. 创建其他路由
// 创建一个首页路由
const indexRoute = createRoute({
getParentRoute: () => rootRoute, // 指定父路由为根路由
path: ‘/’, // 指定 URL 路径
component: () => (

欢迎来到首页!

),
})

// 创建一个关于页面路由
const aboutRoute = createRoute({
getParentRoute: () => rootRoute,
path: ‘/about’,
component: () => (

关于我们

这是一个关于页面。

),
})

// 3. 将路由组合到路由树中
// 注意:根路由是顶级元素,其他路由是它的子元素。
// 路由的顺序不重要,路由器会根据路径匹配。
export const routeTree = rootRoute.addChildren([indexRoute, aboutRoute])

// === 类型生成 ===
// 为了启用类型安全,我们需要生成路由的类型定义。
// Tanstack Router 提供了一个 CLI 工具来完成这个任务。
// 首先,确保你已经安装了 @tanstack/router-cli:
// npm install -D @tanstack/router-cli
// yarn add -D @tanstack/router-cli
// pnpm add -D @tanstack/router-cli

// 在你的 package.json 中添加一个脚本:
// “scripts”: {
// “generate-types”: “npx @tanstack/router-cli generate”
// }

// 运行 npm run generate-types 来生成类型文件(通常在 src/tanstack-router-generated.d.ts)
// 这个文件需要被你的 tsconfig.json 包含。Vite 或 Create React App 通常会自动包含 src/ 下的所有 .d.ts 文件。

// 在生成类型后,你可以在这个文件的末尾导入它们,或者在你的 tsconfig.json 中引用生成的类型文件。
// import {} from “./tanstack-router-generated” // 导入生成的类型(如果需要的话)
“`

2. 在应用入口文件中设置路由器

现在,在 src/main.tsx (或类似文件) 中,我们需要导入路由树并创建路由器实例,然后使用 RouterProvider 组件包裹你的应用根组件。

“`typescript
// src/main.tsx
import ReactDOM from ‘react-dom/client’
import ‘./index.css’
import { RouterProvider, createRouter } from ‘@tanstack/react-router’

// 导入我们在 src/routeTree.ts 中定义的路由树
import { routeTree } from ‘./routeTree’

// 创建路由器实例
// 你可以传递一些选项,例如 history mode (‘browser’ 是默认值,使用浏览器 History API)
const router = createRouter({ routeTree })

// 为了启用类型安全,我们需要给路由器一个类型定义
// 这是通过模块扩展来实现的,它会读取 src/tanstack-router-generated.d.ts 文件
// 将以下代码块添加到你的 src/main.tsx (或 src/routeTree.ts) 文件中:
declare module ‘@tanstack/react-router’ {
interface Register {
router: typeof router
}
}

// 获取应用挂载的根元素
const rootElement = document.getElementById(‘root’)!

// 使用 ReactDOM.createRoot 渲染应用
if (!rootElement.innerHTML) {
const root = ReactDOM.createRoot(rootElement)
root.render(
// 使用 RouterProvider 包裹你的应用根组件
// router 属性接收上面创建的 router 实例

)
}
“`

3. 生成类型

如上所述,为了启用类型安全,你需要运行类型生成命令。

bash
npm run generate-types # 或者 yarn generate-types / pnpm generate-types

第一次运行后,你会看到在 src/ 目录下生成了一个名为 tanstack-router-generated.d.ts 的文件。这个文件包含了你的路由结构的类型定义。保持这个文件在你的项目中,并且每次更改路由配置 (添加、删除、修改路由) 后,都应该重新运行这个命令。

现在,如果你启动你的开发服务器 (npm startnpm run dev),你应该能够看到首页和关于页面,并且可以通过浏览器地址栏直接访问 //about

核心概念详解

1. 路由树 (Route Tree) 与嵌套路由 (Nested Routes)

Tanstack Router 最核心的概念之一是路由树。你不是定义扁平的路由列表,而是构建一个层次结构。

  • 根路由 (createRootRoute): 是路由树的起点,通常没有对应的 URL 路径,作为应用布局的容器。
  • 普通路由 (createRoute): 具有 path 属性,指定对应的 URL 片段,并且必须通过 getParentRoute 指定父路由。
  • 嵌套: 通过 addChildren 方法将子路由添加到父路由上,构建出路由树。例如,/posts/posts/$postId 的父路由。

示例:更复杂的路由树

假设我们有一个博客应用,需要以下路由:

  • / (首页)
  • /about (关于页面)
  • /posts (文章列表页)
  • /posts/$postId (单篇文章详情页,$postId 是一个路由参数)
  • /posts/$postId/comments (单篇文章的评论列表页)

对应的路由树结构和定义会是这样的:

“`typescript
// src/routeTree.ts (示例片段)
import { createRootRoute, createRoute, Outlet } from ‘@tanstack/react-router’
// … 导入你的组件

export const rootRoute = createRootRoute({
component: () => (
<>

{/ 稍后使用 Link /}
首页
关于
文章列表

{/ 根路由的 Outlet /}

),
})

const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: ‘/’,
component: () =>

首页

,
})

const aboutRoute = createRoute({
getParentRoute: () => rootRoute,
path: ‘/about’,
component: () =>

关于我们

,
})

// 定义 /posts 父路由 (通常作为布局或数据加载层)
const postsRoute = createRoute({
getParentRoute: () => rootRoute,
path: ‘posts’, // 注意这里没有前导斜杠 ‘/’
component: () => (

文章区域

{/ /posts 的 Outlet,用于渲染子路由 /}

),
})

// 定义 /posts/$postId 子路由
const postIdRoute = createRoute({
getParentRoute: () => postsRoute, // 父路由是 postsRoute
path: ‘$postId’, // 路径参数以 ‘$’ 开头
component: () => {
// 如何获取参数?稍后讲解!
return

文章详情页

},
})

// 定义 /posts/$postId/comments 子路由
const postCommentsRoute = createRoute({
getParentRoute: () => postIdRoute, // 父路由是 postIdRoute
path: ‘comments’, // 相对于父路由的路径
component: () =>

评论列表

,
})

// 将所有路由添加到路由树中
export const routeTree = rootRoute.addChildren([
indexRoute,
aboutRoute,
postsRoute.addChildren([ // postsRoute 嵌套了两个子路由
postIdRoute.addChildren([postCommentsRoute]), // postIdRoute 又嵌套了 comments 路由
]),
])

// 别忘了运行 generate-types
“`

工作原理:

当用户访问 /posts/123/comments 时,Tanstack Router 会匹配以下路由层级:

  1. rootRoute
  2. postsRoute (匹配 posts)
  3. postIdRoute (匹配 $postId123)
  4. postCommentsRoute (匹配 comments)

渲染时,它们会按照从上到下的顺序层层渲染组件,并在父路由的 Outlet 位置渲染子路由的组件。

  • rootRoute 的 component 渲染,其 Outlet 渲染 postsRoute 的 component。
  • postsRoute 的 component 渲染,其 Outlet 渲染 postIdRoute 的 component。
  • postIdRoute 的 component 渲染,其 Outlet 渲染 postCommentsRoute 的 component。
  • postCommentsRoute 的 component 渲染,因为它是叶子节点,不再有 Outlet

这种结构非常适合构建具有共享布局的区域,例如侧边栏、Tab 导航等。

2. Link 组件:导航的基石

在 Tanstack Router 中进行客户端导航,你应该使用 Link 组件,而不是普通的 <a> 标签 (除非你需要完全的页面刷新)。Link 组件提供了客户端路由的好处,例如平滑过渡、不刷新页面、以及利用路由的数据加载能力。

“`typescript
// 导入 Link 组件
import { Link } from ‘@tanstack/react-router’

function MyApp() {
return (
<>

{/ 基本链接 /}
首页
关于

    {/* 带有参数的链接 */}
    {/* to="/posts/$postId" 中,$postId 会被替换 */}
    <Link to="/posts/$postId" params={{ postId: '1' }}>
      文章 #1
    </Link>
    <Link to="/posts/$postId" params={{ postId: 'abc' }}>
      文章 #abc
    </Link>

    {/* 带有参数和搜索参数的链接 */}
    {/* search 参数是一个对象,会转换为 URL search string (?key1=value1&key2=value2) */}
    <Link
      to="/posts/$postId"
      params={{ postId: '2' }}
      search={{ filter: 'latest', page: 1 }}
    >
      文章 #2 (最新,第一页)
    </Link>

    {/* 链接到嵌套路由 */}
    <Link to="/posts/$postId/comments" params={{ postId: '1' }}>
      文章 #1 评论
    </Link>
  </div>
  <hr />
  {/* Outlet */}

)
}
“`

Link 组件的关键属性:

  • to: 指定目标路由的路径。这是类型安全的!如果你输入的路径不存在或格式不正确,TypeScript 会报错 (前提是你已经生成了类型)。你可以使用参数占位符 ($postId),但需要在 params 属性中提供实际值。
  • params: 一个对象,用于为路由路径中的参数占位符 ($paramName) 提供值。这也是类型安全的!你需要为 to 路径中定义的所有参数提供值,并且值必须符合期望的类型。
  • search: 一个对象,用于定义 URL 的搜索参数 (?key=value&...)。这也是类型安全的!如果你在路由定义中指定了 search 参数的类型,这里会强制校验。
  • activeProps: 当链接对应的路由处于激活状态时,应用于 <a> 元素的属性 (例如 { className: 'active', style: { fontWeight: 'bold' } })。
  • inactiveProps: 当链接不处于激活状态时,应用于 <a> 元素的属性。
  • activeOptions: 精细控制链接激活状态的匹配逻辑 (例如 exact 匹配)。

Link 组件通过类型安全极大地减少了手动拼接 URL 字符串可能引入的错误。

3. 访问路由信息:参数、搜索参数、导航

在组件内部,你需要访问当前路由的动态信息,比如路径参数 ($postId) 和搜索参数 (?filter=...). Tanstack Router 提供了一系列 hooks 来实现这一点。

  • useParams(): 获取当前路由的路径参数。
  • useSearch(): 获取当前路由的搜索参数。
  • useMatchRoute(): 用于检查一个给定的路径是否匹配当前路由或其子路由。
  • useNavigate(): 用于进行编程式导航 (例如,表单提交成功后跳转到详情页)。

示例:在组件中使用 hooks

“`typescript
import { createRoute, useParams, useSearch, useNavigate } from ‘@tanstack/react-router’
import { postsRoute } from ‘./routeTree’ // 导入父路由

// 定义 /posts/$postId 路由的组件
function PostDetail() {
// 获取路径参数。postId 的类型是自动推断的!
const { postId } = useParams({ from: postIdRoute.id }) // { from: … } 可选,用于指定从哪个路由获取参数,确保类型安全

// 获取搜索参数。filter 和 page 的类型取决于你在路由定义中是否指定了 search 参数的类型
const searchParams = useSearch({ from: postIdRoute.id })
// 例如,如果你定义了 search: z.object({ filter: z.string().optional(), page: z.number().optional() })
// searchParams 的类型将是 { filter?: string, page?: number }

// 获取导航函数
const navigate = useNavigate()

// 编程式导航示例:跳转到评论页
const goToComments = () => {
navigate({ to: ‘/posts/$postId/comments’, params: { postId } })
}

return (

文章详情: {postId}

搜索参数: {JSON.stringify(searchParams)}

{/ 稍后我们将在这里加载和显示文章内容 /}

)
)
}

// 在 src/routeTree.ts 中定义这个路由
export const postIdRoute = createRoute({
getParentRoute: () => postsRoute,
path: ‘$postId’,
component: PostDetail, // 使用上面的组件
// 可以为 search 参数定义类型,例如使用 Zod
// search: z.object({
// filter: z.string().optional().catch(‘latest’), // 使用 .catch 提供默认值
// page: z.number().optional().catch(1),
// })
})

// 如果你定义了 search 类型,请重新运行 generate-types
“`

useParamsuseSearchfrom 选项:

{ from: postIdRoute.id } 是可选的,但强烈推荐使用。它明确指定了你要从哪个路由定义中获取参数或搜索参数。这使得类型推断更准确,并能在编译时捕获更多错误。postIdRoute.id 是 Tanstack Router 为每个路由自动生成的唯一 ID (或者你可以手动指定 id 属性)。

编程式导航 useNavigate():

navigate 函数是一个非常有用的工具,它允许你在用户交互、异步操作完成后等场景下进行页面跳转。它也接受类型安全的 to, params, search 参数,用法与 Link 组件类似。

“`typescript
const navigate = useNavigate()

// 导航到首页
navigate({ to: ‘/’ })

// 导航到文章详情页,并替换当前历史记录条目
navigate({ to: ‘/posts/$postId’, params: { postId: ‘new-post-id’ }, replace: true })

// 导航到当前路由的父路由
// navigate({ to: ‘..’, search: { newSearch: ‘value’ } }) // 使用 ‘..’ 相对路径
“`

4. 数据加载 (Data Loading)

这是 Tanstack Router 最强大的功能之一。它允许你在路由配置中定义一个 loader 函数,该函数负责获取当前路由所需的数据。路由器会在进入该路由 之前 (或并行) 运行 loader,确保数据在组件渲染时已经可用。

loader 函数的特点:

  • 在路由被匹配时触发,通常在导航发生 之前
  • 接收一个对象作为参数,包含当前路由的 params, search 参数,以及一些其他上下文信息。
  • 可以是同步的,也可以是异步的 (返回 Promise)。
  • 加载到的数据可以通过 useLoaderData() hook 在对应的路由组件中访问。
  • 路由器会自动处理 loader 的加载中和错误状态。

示例:在 postIdRoute 中加载文章数据

首先,定义一个模拟的数据获取函数:

“`typescript
// src/api.ts (模拟 API)
interface Post {
id: string;
title: string;
body: string;
}

const mockPosts: Record = {
‘1’: { id: ‘1’, title: ‘第一篇文章’, body: ‘这是第一篇文章的内容。’ },
‘abc’: { id: ‘abc’, title: ‘文章 ABC’, body: ‘这是文章 ABC 的精彩内容!’ },
};

export async function fetchPostById(postId: string): Promise {
console.log(Fetching post with ID: ${postId}...);
// 模拟网络延迟
await new Promise(resolve => setTimeout(resolve, 500));
return mockPosts[postId];
}
“`

然后,在 postIdRoute 的定义中添加 loader 函数:

“`typescript
// src/routeTree.ts (postIdRoute 部分)
import { createRoute, useParams, useSearch, useLoaderData } from ‘@tanstack/react-router’
import { postsRoute } from ‘./routeTree’
import { fetchPostById } from ‘./api’ // 导入数据获取函数

// 定义 postIdRoute
export const postIdRoute = createRoute({
getParentRoute: () => postsRoute,
path: ‘$postId’,
// === 添加 loader 函数 ===
loader: async ({ params }) => { // loader 接收包含 params 和 search 的对象
// 在 loader 中,params 也是类型安全的!
const { postId } = params;
console.log(Executing loader for postId: ${postId});
// 调用数据获取函数,返回 Promise
return fetchPostById(postId);
},
component: PostDetail, // 使用下面的 PostDetail 组件
})

// 更新 PostDetail 组件以使用 useLoaderData
function PostDetail() {
const { postId } = useParams({ from: postIdRoute.id });
const searchParams = useSearch({ from: postIdRoute.id });

// === 使用 useLoaderData 获取 loader 返回的数据 ===
// 如果 loader 返回的是 undefined 或 null,可以通过泛型指定 union 类型
const post = useLoaderData({ from: postIdRoute.id }) as Awaited>;
// 或者更简单的,直接用 as Post | undefined (如果你知道 loader 返回类型)

// 获取导航函数
const navigate = useNavigate();

const goToComments = () => {
navigate({ to: ‘/posts/$postId/comments’, params: { postId } });
};

// 处理数据未找到的情况
if (!post) {
// Tanstack Router 也可以通过 errorComponent 自动处理,这里是手动示例
return (

文章未找到

ID: {postId}

);
}

// 数据加载成功,显示文章内容
return (

文章详情: {post.title} (ID: {post.id})

搜索参数: {JSON.stringify(searchParams)}

{post.body}

);
}

// 别忘了运行 generate-types
“`

加载状态和错误处理:

loader 正在执行时,Tanstack Router 会自动管理路由的状态。你可以通过 useRouterState() hook 访问全局路由状态,或者通过 pendingComponenterrorComponent 在路由定义中指定加载中和错误时渲染的组件。

typescript
// 在 src/routeTree.ts 中为 postIdRoute 添加加载中和错误组件
export const postIdRoute = createRoute({
getParentRoute: () => postsRoute,
path: '$postId',
loader: async ({ params }) => {
const { postId } = params;
const post = await fetchPostById(postId);
if (!post) {
// 如果 loader 返回 falsy 值,可以手动抛出错误
throw new Error(`Post with ID "${postId}" not found.`);
}
return post;
},
component: PostDetail,
// === 添加加载中和错误组件 ===
pendingComponent: () => <div className="p-2">加载中...</div>, // loader 正在执行时显示
errorComponent: ({ error }) => ( // loader 抛出错误时显示
<div className="p-2 text-red-500">
<h3>加载文章失败</h3>
<p>{error.message}</p> {/* 访问 loader 抛出的错误 */}
</div>
),
})

现在,当访问 /posts/1/posts/abc 时,你会先看到“加载中…”提示,然后显示文章详情。如果访问一个不存在的文章 ID (例如 /posts/999),你会看到错误信息。

通过 loader 函数,我们将数据获取逻辑与组件渲染解耦,并让路由器负责管理数据加载的整个生命周期,包括并发加载、缓存(默认有基础缓存,与 Tanstack Query 集成更强大)、加载中和错误状态。

5. 类型安全 (Type Safety) 的力量

我们已经多次提及类型安全,现在来具体看看它是如何工作的以及它带来的好处。

当你运行 npm run generate-types 时,@tanstack/router-cli 会扫描你的 routeTree.ts 文件,并生成一个 TypeScript 定义文件 (tanstack-router-generated.d.ts)。这个文件包含了关于你的路由结构、路径、参数、搜索参数以及 loader 返回值的详细类型信息。

然后在 src/main.tsx 中,通过 declare module '@tanstack/react-router' { ... } 将这些生成的类型注册到 @tanstack/react-router 模块中。

好处:

  • 编译时错误检测:

    • 错误的路径: Link to="/non-existent-route"> 会导致 TypeScript 错误,因为它知道这个路径不存在。
    • 遗漏或错误的参数: Link to="/posts/$postId"> 但没有提供 params,或者 params 中缺少 postId 键,或者 postId 的值类型不匹配 (如果你对参数定义了 stricter 类型),TypeScript 都会报错。
    • 遗漏或错误的搜索参数: 如果你对某个路由的 search 定义了 Zod 模式,那么在 Linknavigate 中提供错误的 search 参数类型或遗漏必填项时,TypeScript 会报错。
    • 访问不存在的参数/搜索参数: 在组件中,useParams({ from: postIdRoute.id }) 返回的对象是强类型的,你无法访问一个在路由定义中不存在的参数,例如 params.nonExistentParam
  • 智能提示 (IntelliSense): 在编写 Linkto 属性值时,编辑器会根据你已定义的路由提供路径建议。在编写 paramssearch 对象时,编辑器会提示你需要提供的键及其期望的类型。在使用 useParamsuseSearch 的返回值时,编辑器会准确地知道可用属性及其类型。

这种在开发初期就能发现路由相关错误的能力,极大地提高了开发效率和代码的健壮性,尤其是在大型和团队协作的项目中。

进一步探索 (简要提及)

本教程涵盖了 Tanstack Router 的核心概念。掌握这些已经足够让你构建一个功能完善的应用。但 Tanstack Router 还有更多高级特性值得探索:

  • 验证 (Validation): 使用 Zod 或其他验证库来验证路由参数 (params) 和搜索参数 (search) 的格式和类型。可以在路由定义中通过 validateSearchvalidateParams 选项进行配置。
  • 身份验证和授权 (beforeLoad): 在路由加载数据或渲染组件之前执行异步逻辑,例如检查用户是否登录,或者是否有权限访问某个页面。可以通过 beforeLoad 选项实现,并可以重定向或中止导航。
  • 路由配置 (Route Configuration): 除了 path, component, loader 等,还有许多其他配置选项,如 pendingComponent, errorComponent, staleTime, gcTime (与数据加载缓存相关), caseSensitive, strict, 等。
  • 文件系统路由 (File System Routing): Tanstack Router 团队正在开发一个基于文件系统的路由插件,类似于 Next.js 或 Remix,可以根据文件结构自动生成路由配置,进一步简化路由定义。
  • 与 Tanstack Query 集成: 虽然内置 loader 已经很强大,但将其与 Tanstack Query 结合可以获得更细粒度的缓存控制、数据同步和后台更新等高级功能。

总结

Tanstack Router 是一个现代、强大且注重开发者体验的路由库。它通过路由树结构组织路由,利用类型安全在编译时捕获错误,提供强大的数据加载能力简化异步操作并优化性能,并提供直观的Link组件和Hooks进行导航和访问路由信息。

虽然与 React Router 等传统库相比,它的概念可能稍有不同,特别是数据加载部分,但一旦掌握,你会发现它能显著提升开发效率和应用质量。

本教程为你奠定了坚实的基础。现在,你应该能够:

  • 安装并设置 Tanstack Router。
  • 定义根路由、普通路由和嵌套路由。
  • 使用 Link 组件进行类型安全的导航。
  • 在组件中获取路由参数和搜索参数。
  • 在路由定义中实现数据加载 (loader)。
  • 理解类型安全的好处并生成类型文件。

最好的学习方式是实践。尝试在你自己的项目中应用这些概念,创建更复杂的路由结构,实现带有数据加载的页面,并亲身体验类型安全带来的便利。

如果你遇到问题或想学习更高级的功能,Tanstack Router 的官方文档是最佳资源。祝你在使用 Tanstack Router 的旅程中一切顺利!


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部