Next.js中如何正确实现无sessionStorage时条件渲染组件并避免Hydration错误?
解决Authenticated组件的Hydration错误
你的代码出现Hydration错误的核心原因是:服务端渲染阶段没有window对象,sessionStorage.getItem('token')返回null,此时组件返回空片段;但客户端Hydrate时,若本地存在token,组件会立刻渲染子元素,导致服务端与客户端的初始输出不匹配。
以下是修正后的实现方案,能彻底避免Hydration冲突:
'use client'; import { useState, useEffect } from 'react'; import { useRouter } from 'next/navigation'; // 若需要跳转登录页则引入 export const Authenticated = ({ children }) => { const [isAuthenticated, setIsAuthenticated] = useState(false); const [isLoading, setIsLoading] = useState(true); const router = useRouter(); // 仅在客户端挂载后检查token,避免服务端与客户端渲染差异 useEffect(() => { const token = sessionStorage.getItem('token'); setIsAuthenticated(!!token); setIsLoading(false); // 未认证时跳转登录页(可选) if (!token) { router.push('/login'); } }, [router]); // 加载状态:服务端和客户端初始都返回null,保证输出一致 if (isLoading) { return null; // 也可替换为自定义加载组件,如<div>验证中...</div> } // 未认证时返回空或已完成跳转 if (!isAuthenticated) { return null; } return <main>{children}</main>; };
关键说明:
- 用
useState维护isLoading状态,服务端渲染时始终为true,返回null,确保服务端与客户端初始输出一致。 useEffect仅在客户端Hydrate完成后执行,此时读取sessionStorage并更新认证状态,后续的UI变更属于客户端交互阶段,不会触发Hydration错误。- 可选:添加登录页跳转逻辑,在未认证时自动导向登录页面,提升用户体验。
内容的提问来源于stack exchange,提问作者Michael Lynch
相关产品推荐
相关产品推荐

