NextJS中Supabase Auth水合(Hydration)错误的原因及修复方案
NextJS水合错误(Hydration failed)的原因与修复方案
错误原因
- 服务器与客户端初始状态不匹配:服务器端无法读取浏览器中的Supabase session(存储在cookie或localStorage),初始
session值为null,会渲染Auth登录组件;但客户端可能已有缓存的session,在hydration阶段,useEffect执行前若客户端快速获取到session,会导致客户端渲染结果与服务器端不一致,触发水合错误。 - session存在时无有效返回内容:当
session存在时,组件未返回任何JSX(实际返回undefined),若客户端在hydration过程中session状态从null变为存在,UI会从Auth组件突然变为空,进一步加剧水合不匹配问题。
修复方法
针对上述问题,通过以下代码修改解决:
修改后的完整代码
"use client"; import { useState, useEffect } from "react"; import { supabase } from "@/lib/supabaseClient"; import { Auth } from "@supabase/auth-ui-react"; import { ThemeSupa } from "@supabase/auth-ui-shared"; import { Session } from "@supabase/supabase-js"; import { useRouter } from "next/navigation"; export default function Login() { const [session, setSession] = useState<Session | null>(null); const [isLoading, setIsLoading] = useState(true); const router = useRouter(); useEffect(() => { const fetchSession = async () => { const { data: { session } } = await supabase.auth.getSession(); setSession(session); setIsLoading(false); }; fetchSession(); const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, session) => { setSession(session); if (session) router.push("/"); }); return () => subscription.unsubscribe(); }, [router]); if (isLoading) { return ( <div className="min-h-screen flex items-center justify-center"> <p>加载中...</p> </div> ); } if (!session) { return ( <div className="min-h-screen flex flex-col items-center justify-center"> <div className="w-full max-w-md"> <Auth supabaseClient={supabase} appearance={{ theme: ThemeSupa }} providers={[]} /> </div> </div> ); } return ( <div className="min-h-screen flex items-center justify-center"> <p>已登录,正在跳转...</p> </div> ); }
关键修改点说明
- 添加加载状态
isLoading:初始设为true,服务器端和客户端初始渲染都显示加载UI,确保hydration阶段两端内容完全一致,避免状态突变导致的不匹配。 - 补充session存在时的返回内容:不再返回
undefined,而是显示跳转提示,同时通过useRouter自动跳转到首页,保证UI始终有有效输出。 - 优化session获取逻辑:用
async/await异步获取session,完成后再切换加载状态,确保客户端在hydration完成后才更新UI;移除不必要的typeof window判断("use client"组件已确保代码只在客户端执行)。
内容的提问来源于stack exchange,提问作者NBRCS
相关产品推荐
相关产品推荐

