本文档介绍了 React Router 中的 hydration(数据同步)过程和数据加载策略,重点关注服务器端渲染 (SSR) 和客户端执行之间的交互。有关创建 loader 和 action 的信息,请参阅 Data APIs,有关通用 SSR 架构,请参阅 Server-Side Rendering。
Hydration 是客户端 React 应用程序“接管”服务器端工作过程,将事件处理器附加到服务器渲染的 HTML 并恢复应用程序状态。在 React Router 中,这涉及到在服务器和客户端之间仔细传递路由匹配数据、loader 数据和错误状态。
来源:packages/react-router/lib/dom-export/hydrated-router.tsx79-210 packages/react-router/lib/server-runtime/server.ts416-512
React Router v7 实现了一种“Single Fetch”(单一请求)数据加载策略,它会整合数据请求以优化性能。它不像每个路由的 loader 都单独发起网络请求,而是将它们批量处理成一个请求。
.data 请求。turbo-stream 启用的流式格式传输。来源:packages/react-router/lib/dom/ssr/single-fetch.tsx156-333 packages/react-router/lib/server-runtime/single-fetch.ts45-77
来源:packages/react-router-dev/vite/plugin.ts388-417 packages/react-router/lib/server-runtime/server.ts228-273
Hydration 状态包含从服务器序列化到客户端的 loader 数据、action 数据和错误。 HydratedRouter 组件负责引导此过程。
在 hydration 过程中
StaticHandlerContext 中HydratedRouter 组件window.__reactRouterContext 解码 hydration 状态来源:packages/react-router/lib/router/router.ts286-356 packages/react-router/lib/dom-export/hydrated-router.tsx128-196
React Router 支持局部 hydration,这是一种技术,其中一些路由立即使用服务器数据,而另一些在 hydration 过程中获取新数据。
对于具有客户端 loader 的路由,React Router 提供了一个 HydrateFallback 组件,该组件在 hydration 期间渲染,直到客户端数据可用为止。
在 hydration 期间,React Router 检测到以下路由:
clientLoader 函数HydrateFallback 组件对于这些路由,HydrateFallback 组件会在初始 hydration 期间渲染,并且客户端 loader 会被执行以获取新数据。
来源:packages/react-router/lib/dom-export/hydrated-router.tsx145-187 packages/react-router/lib/dom/ssr/routes.tsx65-117
一旦 hydration 完成,React Router 会使用 Single Fetch 策略或传统的客户端数据加载来处理导航。
React Router 区分不同类型的 loaders
| Loader 类型 | 执行 | 用于 | Hydration 行为 |
|---|---|---|---|
loader | 服务器端 | 服务器渲染数据 | 从服务器状态 hydration |
clientLoader | 客户端 | 仅客户端数据 | 在 hydration 期间/之后运行 |
| 两者 | Server + Client (服务器 + 客户端) | 混合方法 | 服务器数据最初可用,在客户端刷新 |
来源:packages/react-router/lib/dom/ssr/single-fetch.tsx285-320 packages/react-router/lib/dom-export/hydrated-router.tsx149-194
React Router 采用“Fog of War”(战争迷雾)的路由发现方式,即路由在用户通过应用程序进行导航时按需加载。
这种方法
路由器维护一个已发现路由的缓存,并在导航过程中根据需要获取新路由。
来源:packages/react-router/lib/dom/ssr/fog-of-war.ts29-97 packages/react-router-dev/vite/plugin.ts326-384
在服务器上,React Router
StaticHandlerContext 中捕获数据和错误turbo-stream 对数据进行编码来源:packages/react-router/lib/server-runtime/server.ts387-512 packages/react-router/lib/router/router.ts392-404
在客户端,React Router
window.__reactRouterContext 解码 hydration 状态HydratedRouter 组件是此过程的主要入口点,它使用 hydration 状态设置路由器并管理从服务器到客户端渲染的过渡。
来源:packages/react-router/lib/dom-export/hydrated-router.tsx77-210 packages/react-router/lib/dom/global.ts1-17
React Router 还支持 SPA 模式,并可选预渲染,采用混合方法
prerender: true)来源: integration/vite-spa-mode-test.ts21-150 integration/vite-prerender-test.ts156-287
在水合过程中处理错误需要特别考虑
该系统确保错误不会中断水合过程,并且会激活适当的错误边界。
来源: packages/react-router/lib/server-runtime/server.ts442-466 packages/react-router/lib/dom-export/hydrated-router.tsx190-195
React Router 的水合(hydration)和数据加载架构,通过单一获取策略、局部水合以及“战争迷雾”(Fog of War)方法协同工作,实现了从服务器渲染内容到交互式客户端应用程序的平滑过渡,优化了性能,同时保持了开发者的易用性。