You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 06:49:57