关于 hydration-guardian
hydration-guardian 是面向 React SSR 的技能,用于诊断和避免服务端 HTML 与客户端树不一致。它涵盖 React 19 的数据衔接、渲染策略和错误监控方法。
主要功能
- 01诊断水合不匹配原因
- 02使用 Suspense 选择性水合
- 03通过 React 19 use() 衔接数据
- 04用 'use cache' 避免数据漂移
- 05验证渲染后的 DOM 状态
- 06监控水合恢复与错误
适用场景
- 01排查文本或标记不匹配
- 02处理 SSR 中的纯客户端内容
- 03减少日期和动态数据造成的漂移
- 04审查生产环境中的水合警告
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ oakoss/ agent-skills --skill hydration-guardian安装后在 Claude Code 中输入/hydration-guardian确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/common-mismatches.mdselective-hydration.mduse-cache-patterns.mdvalidation-techniques.md详细介绍
Hydration 守护
概述
确保服务端渲染的 HTML 与客户端 React 树之间的完整性,避免出现任何不匹配。涵盖 Hydration 错误诊断、通过 Suspense 边界实现选择性 Hydration、使用 React 19 use() Hook 构建确定性数据桥接、使用 'use cache' 消除数据漂移、为仅客户端内容实现双阶段渲染、利用 React 19 的单差异 Hydration 错误报告精确定位不匹配,以及自动验证渲染后的 DOM 状态。
适用场景: 调试 Hydration 不匹配错误、修复文本内容不匹配、处理浏览器扩展导致的 DOM 污染、实现确定性数据桥接、优化 SSR/客户端 Hydration 性能,以及通过 onRecoverableError 设置错误监控。
不适用场景: 不使用 SSR 的纯客户端 React 应用、不使用 Hydration 的静态网站,以及仅提供 API 的后端。
快速参考
| 模式 | 方案 | 要点 |
|---|---|---|
| 选择性 Hydration | <Suspense fallback={...}> 边界 | 独立 Hydration;优先响应用户交互 |
| 确定性桥接 | 使用 use(serverPromise) 代替 useEffect | 直接从服务端向客户端过渡数据(React 19) |
| 缓存指令 | 在数据获取函数中使用 'use cache' | Hydration 期间与客户端共享完全相同的服务端结果 |
| 双阶段渲染 | 使用 useState + useEffect 处理仅客户端内容 | 首次渲染与服务端一致;第二次渲染时添加客户端内容 |
| 跳过客户端内容渲染 | 使用 ssr: false 的 next/dynamic | 完全排除该组件的服务端渲染 |
| 错误监控 | 在 hydrateRoot 上使用 onRecoverableError | 检测并报告静默的 Hydration 恢复 |
| 错误报告 | React 19 单差异错误格式 | 通过统一差异输出精确定位不匹配的位置 |
| 错误回调 | onUncaughtError、onCaughtError | 在 createRoot/hydrateRoot 上进行精细化错误处理 |
| 日期/时间安全 | UTC 标准化或与服务端同步的上下文 | 防止因区域设置而产生的 Hydration 不匹配 |
| 扩展兼容性 | 在启用常见浏览器扩展的情况下测试 | 检测翻译工具、深色模式工具导致的 DOM 污染 |
Hydration 错误诊断
| 错误消息 | 可能原因 | 修正措施 |
|---|---|---|
Text content did not match | 非确定性渲染(日期、随机值) | 使用双阶段渲染或 suppressHydrationWarning |
Expected server HTML to contain | 客户端渲染了服务端未渲染的内容 | 将仅客户端代码移至 useEffect 或动态导入 |
Hydration failed | HTML 嵌套无效(在 <p> 内嵌套 <p>) | 修正 HTML 结构;浏览器自动纠正会导致内容漂移 |
Extra attributes from server | 服务端属性未出现在客户端 | 确保属性一致,或使用 suppressHydrationWarning |
There was an error while hydrating | 扩展修改了 DOM 或存在严重不匹配 | 检查浏览器扩展;验证 HTML 是否有效 |
常见错误
| 错误 | 正确做法 |
|---|---|
在容器元素上使用 suppressHydrationWarning | 修复根本原因;仅在存在不可避免差异的叶子元素上抑制警告 |
在渲染主体中访问 window 或 document | 将仅客户端代码封装在 useEffect 中,或使用 next/dynamic 并设置 ssr: false |
使用 Math.random() 或 new Date(),但没有稳定种子 | 使用 UTC 标准化、服务端缓存值或两遍渲染 |
| 忽略生产环境中静默的水合恢复 | 在 hydrateRoot 上配置 onRecoverableError 以记录并监控 |
使用 dangerouslySetInnerHTML,但服务端和客户端内容不一致 | 确保内容相同,或通过更改专用的 key 强制重新挂载 |
在渲染过程中检查 typeof window !== 'undefined' | 使用两遍渲染;服务端也会执行此检查(结果为 false) |
在 <p> 中嵌套 <p>,或在 <p> 中嵌套 <div> | 修复无效的 HTML 嵌套;浏览器会自动纠正,导致服务端与客户端不一致 |
委派
- 扫描渲染后的页面,查找隐藏的水合警告:使用
ExploreAgent 配合 Chrome DevTools 运行水合审计脚本 - 修复多个路由中的水合不匹配问题:使用
TaskAgent 隔离、修正并验证每个受影响的组件 - 为新功能设计水合安全的架构:使用
PlanAgent 在 Suspense 边界、两遍渲染和缓存模式之间进行选择
参考资料
评论
支持 Markdown