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
相关产品推荐
相关产品推荐

