## 防止水合(Hydration)不匹配且无闪烁
当渲染依赖于客户端存储(localStorage、cookies)的内容时,通过注入一个在 React 水合之前同步更新 DOM 的脚本,可以避免 SSR 崩溃和水合后的闪烁问题。
**错误示例(导致 SSR 崩溃):**
tsx
function ThemeWrapper({ children }: { children: ReactNode }) {
// localStorage 在服务器上不可用 - 会抛出错误
const theme = localStorage.getItem('theme') || 'light'
return (
{children}
)
}
服务器端渲染将失败,因为 `localStorage` 未定义。
**错误示例(视觉闪烁):**
tsx
function ThemeWrapper({ children }: { children: ReactNode }) {
const [theme, setTheme] = useState('light')
useEffect(() => {
// 在水合后运行 - 导致可见的闪烁
const stored = localStorage.getItem('theme')
if (stored) {
setTheme(stored)
}
}, [])
return (
{children}
)
}
组件首先使用默认值 (`light`) 渲染,然后在水合后更新,导致内容出现短暂的错误显示。
**正确示例(无闪烁,无水合不匹配):**
tsx
function ThemeWrapper({ children }: { children: ReactNode }) {
return (
{children}
)
}
内联脚本在显示元素之前同步执行,确保 DOM 已经具有正确的值。没有闪烁,也没有水合不匹配。
这种模式特别适用于主题切换、用户偏好设置、身份验证状态以及任何应该立即渲染而不闪烁默认值的客户端数据。