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

Next.js 13 中如何修复认证组件的 Hydration 错误?

修复 Next.js 13 Hydration 失败问题

错误原因

你的认证组件在服务器端渲染时返回 null,但客户端首次 hydration 时会立刻检查 localStorage,可能直接渲染目标组件或跳转路由,导致服务器与客户端初始渲染的 UI 不一致,触发 Hydration 不匹配错误。

修复方案

修改高阶组件,用 useEffect 延迟认证逻辑(useEffect 仅在客户端执行),同时通过状态同步服务器与客户端的初始渲染结果:

import { useRouter } from "next/router";
import { useState, useEffect } from "react";

const withAuth = (WrappedComponent: any) => {
  return (props: any) => {
    const router = useRouter();
    // 初始状态为 null,保证服务器和客户端初始渲染一致
    const [isAuthenticated, setIsAuthenticated] = useState<boolean | null>(null);

    useEffect(() => {
      // 仅在客户端执行认证检查
      const accessToken = localStorage.getItem("token");
      if (!accessToken) {
        router.replace("/authentication/login");
      } else {
        setIsAuthenticated(true);
      }
    }, [router]);

    // 初始渲染返回 null(或加载组件),避免 Hydration 不匹配
    if (isAuthenticated === null) {
      return null;
      // 可选:替换为加载组件提升体验
      // return <div>加载中...</div>
    }

    // 认证通过后渲染目标组件
    return isAuthenticated ? <WrappedComponent {...props} /> : null;
  };
};

export default withAuth;

关键改动说明

  • 状态同步:用 isAuthenticated 状态控制渲染,初始值 null 让服务器和客户端首次渲染均返回相同内容(null)。
  • 延迟认证:useEffect 只在客户端 hydration 完成后执行,此时再检查 localStorage 并处理路由或更新状态,不会破坏 Hydration 过程。
  • 避免顶层操作:不在组件顶层直接访问 localStorage 或执行路由跳转,这类操作仅在客户端有效,会导致服务器与客户端渲染结果不一致。

内容的提问来源于stack exchange,提问作者Arash Barghash

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:53:22