---
id: router.typed-context
kind: contract
product: router
framework: react
locale: zh-CN
revision: 2
sourceCheckedOn: "2026-08-03"
versionRange: "^1"
verifiedAgainst: "@tanstack/react-router@1.170.18"
contentModel: 2
packages:
  - "@tanstack/react-router"
tasks:
  - "inject-router-dependency"
  - "augment-route-context"
  - "before-load-context"
sourceRefs:
  - "https://tanstack.com/router/latest/docs/guide/router-context"
  - "https://tanstack.com/router/latest/docs/framework/react/guide/authenticated-routes"
---

# 建立类型化 Router Context

> 在根路由声明依赖，并通过 beforeLoad 为子树追加可推导的派生上下文。

## 执行契约

- **适用场景:** Loader、beforeLoad 和路由组件需要共享 QueryClient、认证读取器或其他应用级依赖。
- **不要使用:** 不要把频繁变化的页面状态或只属于单个组件的数据塞入 Router Context。
- **前置检查:** 通过注册类型定义最小接口，并确定依赖在 RouterProvider 外部如何取得。
- **验证结果:** 缺少必需依赖时编译失败，父级 beforeLoad 扩展的 Context 在子路由中保持准确类型。
- **失败模式:** Context 变成 any 通常来自缺少模块注册或在创建 Router 时做了强制断言。
- **安全边界:** Context 可帮助传递鉴权能力，但不能把客户端认证状态视为服务端授权证据。

## 根契约

使用 createRootRouteWithContext<RouterContext>() 声明根依赖。createRouter.context 必须满足该类型；不要用非空断言掩盖真正缺失的服务。

File: `src/routes/__root.tsx`

```tsx
import { createRootRouteWithContext } from '@tanstack/react-router'
import type { QueryClient } from '@tanstack/react-query'

type RouterContext = { queryClient: QueryClient }

export const Route = createRootRouteWithContext<RouterContext>()({
  component: RootDocument,
})
```

## 子树扩展

beforeLoad 可以同步或异步返回新 context，返回值会与父级 context 合并并传给子路由。只返回子树真正需要的稳定事实，避免每个 loader 重复计算。

## 权限边界

beforeLoad 可以阻止导航或重定向，但客户端路由状态可以被绕过。服务端数据入口必须独立验证身份与权限，不能把 canEdit 这类 context 布尔值当作授权证明。

## Official sources

- https://tanstack.com/router/latest/docs/guide/router-context
- https://tanstack.com/router/latest/docs/framework/react/guide/authenticated-routes
