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

Next.js AuthGuard组件首次加载Local Storage未读取,刷新后恢复正常

解决Next.js AuthGuard首次加载无法读取LocalStorage导致的路由跳转问题

你的问题核心在于Next.js的服务端渲染特性:首次页面渲染是在服务端完成的,此时window对象不存在,直接调用window.localStorage.getItem('userData')会取不到值,再加上auth.user===null的判断,组件会直接返回fallback加载器。只有当页面完成客户端hydration后刷新,客户端环境下才能正常读取LocalStorage,触发路由跳转逻辑。

修改方案

下面是调整后的代码,同时附上关键修改说明:

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

const AuthGuard = props => {
  const { children, fallback } = props;
  const auth = useAuth();
  const router = useRouter();
  // 标记当前是否处于客户端环境
  const [isClient, setIsClient] = useState(false);

  useEffect(() => {
    // 组件挂载后才切换为客户端环境状态
    setIsClient(true);
  }, []);

  useEffect(() => {
    // 路由未就绪或非客户端环境时不执行逻辑
    if (!router.isReady || !isClient) return;

    // 仅在客户端读取LocalStorage
    const hasUserData = window.localStorage.getItem('userData');
    if (auth.user === null && !hasUserData) {
      const returnUrlConfig = router.asPath !== '/' 
        ? { query: { returnUrl: router.asPath } } 
        : {};
      router.replace({ pathname: '/login', ...returnUrlConfig });
    }
  }, [router.isReady, auth.user, isClient, router.asPath]);

  // 服务端阶段或auth仍在加载时,返回fallback
  if (!isClient || auth.loading) {
    return fallback;
  }

  // 客户端环境下,用户未登录时返回null(路由跳转后会自动切换页面)
  if (auth.user === null) {
    return null;
  }

  return <>{children}</>;
};

export default AuthGuard;

关键修改点说明

  • 新增isClient状态:确保只有在客户端环境下才执行LocalStorage读取和路由跳转,避免服务端因window不存在报错
  • 优化useEffect依赖:加入router.isReady、auth.user和router.asPath,保证路由就绪、用户状态变化或路径改变时,都能触发登录判断逻辑
  • 调整渲染条件:服务端阶段或auth加载中才返回fallback;客户端环境下用户未登录时返回null,配合路由跳转完成页面切换,不会一直显示加载器

内容的提问来源于stack exchange,提问作者Yogesh Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 04:16:06