SuperAPI AI 工具集

tanstack-router-core-search-params

前端与建站

查看项目

更新于 10-16 10:24

技能介绍

用途

本技能介绍 TanStack Router 中搜索参数(Search Params)的处理方式。TanStack Router 将搜索参数视为 JSON 优先的应用状态:它们会从 URL 自动解析为结构化对象(数字、布尔值、数组、嵌套对象),并在每个路由上通过 validateSearch 进行校验。

主要能力

  • 通过 validateSearch 对每个路由的搜索参数进行校验。
  • 支持 Zod、Valibot、ArkType 适配器。
  • 类型完全推断,无需手动标注 useSearch() 的返回值。
  • 支持搜索参数继承:父路由的搜索参数会自动合并到子路由。
  • 提供搜索中间件:retainSearchParams(跨导航保留参数)、stripSearchParams(从 URL 中移除默认值),并支持链式组合。
  • 支持在路由器级别自定义序列化(parseSearchWith / stringifySearchWith)。
  • 支持通过 loaderDeps 在 loader 中使用搜索参数。

使用方式

安装(Zod 适配器,推荐)

npm install zod @tanstack/zod-adapter

定义校验

// src/routes/products.tsx
import { createFileRoute } from '@tanstack/react-router'
import { z } from 'zod'

const productSearchSchema = z.object({
  page: z.number().default(1).catch(1),
  filter: z.string().default(''),
  sort: z.enum(['newest', 'oldest', 'price']).default('newest').catch('newest'),
})

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

读取搜索参数

  • 路由组件内:Route.useSearch()
  • 代码分割组件内:getRouteApi('/products') 后调用 routeApi.useSearch()
  • 任意组件:useSearch({ from: '/products' })
  • 宽松访问:useSearch({ strict: false })

写入搜索参数

  • Link 函数形式(保留现有参数):search={(prev) => ({ ...prev, page: prev.page + 1 })}
  • Link 对象形式(替换全部参数):search={{ page: 1, filter: '', sort: 'newest' }}
  • 编程式:useNavigate() 配合 navigate({ search: (prev) => ({ ...prev, sort: e.target.value, page: 1 }) })

搜索中间件

  • retainSearchParams:middlewares: [retainSearchParams(['debug'])]
  • stripSearchParams:middlewares: [stripSearchParams(defaults)]
  • 可链式组合多个中间件。

自定义序列化

import { createRouter, parseSearchWith, stringifySearchWith } from '@tanstack/react-router'

const router = createRouter({
  routeTree,
  parseSearch: parseSearchWith(parse),
  stringifySearch: stringifySearchWith(stringify),
})

在 loader 中使用(loaderDeps)

export const Route = createFileRoute('/products')({
  validateSearch: productSearchSchema,
  loaderDeps: ({ search }) => ({ page: search.page }),
  loader: async ({ deps }) => {
    return fetchProducts({ page: deps.page })
  },
})

适用场景

适用于使用 TanStack Router 构建的 React 应用,需要在 URL 中保存和同步筛选、排序、分页等状态,并希望获得类型安全的校验与读写体验的场景。

限制与注意事项

  • 使用 zodValidator() 且为 Zod v3 时,应使用 @tanstack/zod-adapter 的 fallback(),而非 zod 的 .catch();使用 .catch() 会使输出类型变为 unknown,破坏类型安全。此限制不适用于 Valibot 或 ArkType(它们使用各自的 fallback 机制),也不适用于 Zod v4(v4 应使用 .catch(),且不使用 zodValidator())。
  • 类型完全推断,切勿标注 useSearch() 的返回值。
  • loaderDeps 不应返回整个 search 对象,否则任何搜索参数变化都会导致 loader 重新运行;应只挑选 loader 需要的参数。
  • 不要在搜索参数中传递 Date 对象,应转换为 ISO 字符串。
  • 父路由缺少 validateSearch 会阻止子路由继承共享参数。
  • 使用对象形式的 search 会替换全部搜索参数,若需保留现有参数应使用函数形式。