执行契约
- 适用场景
- 筛选、排序、分页或可分享视图需要由 URL 持有。
- 不要使用
- 不要存放秘密、临时输入或无法安全序列化的大对象。
- 前置检查
- 定义允许的键、运行时验证规则、默认值以及规范化后的 URL 形态。
- 验证结果
- 测试有效、缺失和非法值;刷新、后退与分享链接都必须恢复相同视图。
- 失败模式
- 若一次更新清空其他键,检查 search 更新函数是否基于 previous 合并,而不是创建不完整对象。
- 安全边界
- URL 输入不可信;验证通过仍不代表可以直接拼接 SQL、文件路径或外部请求。
契约
validateSearch 接收解析后但不可信的值。返回值将成为 loader、Route.useSearch() 和子路由看到的搜索类型。
实现
为非法页码提供稳定默认值,并将 status 限制到明确联合。
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/issues/')({
validateSearch: (search: Record<string, unknown>) => ({
page: Math.max(1, Number(search.page) || 1),
status: search.status === 'closed' ? 'closed' as const : 'open' as const,
}),
component: IssuesPage,
})
function IssuesPage() {
const { page, status } = Route.useSearch()
return <p>{status} issues · page {page}</p>
}常见失败
不要在每个组件里重复解析搜索值。不要假设 Number() 一定返回有效数字。如果项目已使用 Zod 或 Valibot,优先复用现有 schema。