页面加载后控制台报 Hydration failed because the initial UI does not match what was rendered on the server,页面闪一下重绘,时间从 12:00 跳成 12:01,服务端和客户端各渲染一遍才对不上,首屏也会闪白。乍看像缓存或者权限的锅,追下去往往不是。
const [now, setNow] = useState(null); useEffect(() => setNow(Date.now()), []);
追下去是这么回事:服务端渲染时执行了 new Date(),客户端二次渲染拿到的时间不同,两边 HTML 对不上,框架只能丢掉服务端结果重新渲染一遍,所以时间类内容最容易踩。
「Hydration 不一致」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。
偶发问题先统计频率,一小时几次和一天一次,查法完全不同。改完顺手把文档补一句,省得下次自己重新推一遍。
具体做法是,和时间相关的渲染统一放到挂载之后再执行,别在服务端算;随机数只在客户端的 useEffect 里生成,服务端不要碰;无法保持一致时加 suppressHydrationWarning 跳过比对。
验收就看一点,刷新页面不再出现 hydration 警告,首屏内容不闪烁也不会闪白,控制台也干净。
