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

React+Next.js本地存储登录授权:useEffect重定向失效排查

问题分析与解决方案

你的代码里有两个核心问题导致重定向失效:

1. 状态更新的异步性导致判断逻辑错误

setValid 和 setRole 是异步操作,在同一个 useEffect 里调用它们之后,立刻用 valid 和 role 状态做判断,拿到的还是初始值(valid: false、role: '')。而且你把 valid 和 role 加到了 useEffect 的依赖数组里,导致状态更新后会再次触发 useEffect,这时候如果 token 验证通过,判断条件就不成立,反而会干扰重定向逻辑。

2. 判断条件逻辑写反

不管是重定向的条件,还是页面内容渲染的条件,都搞反了:

  • 重定向应该是token无效 或者 角色不是USER时触发,你写的是valid !== true && role !== "USER",只有同时满足两个条件才会跳转;
  • 页面内容应该是token有效且角色是USER时才显示,你原来的判断刚好相反,导致验证通过时反而不显示内容。

修正后的代码

"use client";
//modules
import { useState, useEffect } from "react";
import { useRouter } from "next/navigation";

//styles
import styles from "./page.module.sass";

//components
import NewCV from "./components/newCv";
import Cvs from "./components/cvs";
import PersonalInfo from "./components/personalInfo";
import LayoutPicker from "./components/LayoutPicker";

//helpers
import { vaildToken } from "@/app/authorization";

export default function MyPage() {
  const router = useRouter();
  const [catType, setCatType] = useState(0);
  const cat = (type) => setCatType(type);

  const [valid, setValid] = useState(false);
  const [role, setRole] = useState('')

  useEffect(() => {
    const token = localStorage.getItem("token");
    // 直接获取验证结果,不用等状态更新
    const [isValid, userRole] = vaildToken(token);
    setValid(isValid);
    setRole(userRole);

    // 只要token无效或角色不符,就跳转到登录页
    if (!isValid || userRole !== "USER") {
      router.push("/login");
    }
  }, []); // 空依赖数组,确保只执行一次

  return (
    <main className={styles.main}>
      {/* 验证通过才显示页面内容,否则可以加个加载提示 */}
      {valid && role === "USER" ? (
        <div className={styles.container}>
          <LayoutPicker cat={cat} />
          {catType === 1 ? <Cvs /> : catType === 2 ? <NewCV /> : <PersonalInfo />}
        </div>
      ) : (
        <div className={styles.loading}>加载中...</div>
      )}
    </main>
  );
}

关键修改点说明

  • 把 useEffect 的依赖改成空数组,确保组件挂载时只执行一次验证逻辑,避免重复触发;
  • 直接使用 vaildToken 返回的结果做判断,绕开状态更新的异步性问题;
  • 修正重定向和内容渲染的条件逻辑,确保逻辑符合预期;
  • 增加加载状态,避免验证过程中页面出现空白闪烁。

另外补充:不用 useEffect 时会报 localStorage 未定义,是因为 Next.js 的客户端组件会先在服务器端执行一次渲染,而服务器环境没有 localStorage 对象,useEffect 里的代码只会在浏览器端执行,所以能避开这个问题。

内容的提问来源于stack exchange,提问作者Evan Serg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 13:12:52