@
Razio 全部 SSR 肯定没问题,也不会有 Hydration Error ;哪怕用根 HydrationBoundary 把登录状态提前 prefetch ,也不会报错的,我上面就说了呀。
我主要是希望尽可能多静态渲染,只有非 SSR 不可的页面再 SSR ;
右上角那个登录状态,所有页面都要用,所以要是这里用 SSR 来读 cookies 的话所有页面都是 SSR 了,不符合需求;
所以我之前和 4 楼说的一样,右上角那个登录态做成客户端组件,用 useQuery 去查登录态,请求返回之前有个 loading 的样式占位,这一切正常。
现在问题,只要客户端组件多处用到 useQuery (或者 better-auth 的 useSession ,也一样) 来查询登录态,居然能出现 Hydration Error ,这是客户端组件啊,刷新 N 次就能复现一次;如果是上级 layout.tsx 用 SSR 把数据注入 <HydrationBoundary>,那触发的更频繁了,基本刷新 2 次就复现一次。
当然是登录时才有这 Error ,退出登录就好了,刷新 100 次也没 Error 。
对登录 hook 的返回值打 log 发现,如果是这个顺序:A undefined 、B undefined 、C undefined 、A 已登录、B 已登录、C 已登录,这样就正常;
报错的时候是这样:A undefined 、A 已登录、B 已登录、C 已登录,或者是:A undefined 、B undefined 、A 已登录、B 已登录、C 已登录,这样就报错了;
难不成 useQuery() 在预渲染的时候返回值不稳定?如果变的时机提前了,例如在 B 代码运行前就变了或者在 C 代码运行前就变了,就导致后续的若干个组件出问题?
请求数据也都是先根据 isPending 再根据 data 来读取的,想不明白怎么还能这样;本来我以为是 better-auth 的 isPending 有问题,查了一下,确实之前有这个 bug ,但是五月份已经修复并 merged 了;也试了一下不根据 isPending 也是有问题。
也像我说的一样,如果用 useMounted() 来提前区分一次,这样也是 100% 不报错的;
所以我觉得是 Next.js 在预渲染的时候出问题了?毕竟就算是客户端组件也会预渲染。