--- title: 防止水合不匹配且不闪烁 impact: MEDIUM impactDescription: 避免视觉闪烁和水合错误 tags: rendering, ssr, hydration, localStorage, flicker --- ## 防止水合不匹配且不闪烁 当渲染依赖于客户端存储(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}