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

MERN应用中useNavigate()刷新页面后登录跳转失效问题

问题原因

刷新页面后登录无法跳转首页的核心问题是路由守卫没有响应localStorage的token变化:

  • 原代码里的PrivateRoute是普通函数,仅在App组件初始渲染时执行一次。刷新页面后,App初始渲染时localStorage无token,路由判断结果为false,默认指向/login。
  • 登录成功后虽然把token存入localStorage,但App组件不会重新触发渲染,路由守卫的判断逻辑仍停留在初始状态,导致调用navigate("/")后,立刻被路由守卫跳回/login页面。
解决方案

将路由守卫改为响应token变化的React组件,使用状态监听localStorage的更新,同时遵循React Router的官方私有路由实现方式:

修改App.js

import { Navigate, Outlet } from 'react-router-dom';
import { useState, useEffect } from 'react';

// 改写为带状态的私有路由组件
const ProtectedRoute = () => {
  // 初始化状态为当前localStorage中是否有token
  const [hasValidToken, setHasValidToken] = useState(!!localStorage.getItem('jwt'));

  useEffect(() => {
    // 监听localStorage变化,同步token状态
    const handleStorageUpdate = () => {
      setHasValidToken(!!localStorage.getItem('jwt'));
    };

    window.addEventListener('storage', handleStorageUpdate);
    // 组件卸载时移除监听
    return () => window.removeEventListener('storage', handleStorageUpdate);
  }, []);

  // 有token则渲染受保护页面,否则跳转到登录页
  return hasValidToken ? <Outlet /> : <Navigate replace to="/login" />;
};

function App() {
  return (
    <Router>
      <Navbar />
      <Routes>
        {/* 用ProtectedRoute包裹所有需要权限的路由 */}
        <Route element={<ProtectedRoute />}>
          <Route path="/" element={<Home />} />
        </Route>
        <Route path="/login" element={<Login />} />
        <Route path="/register" element={<Register />} />
      </Routes>
    </Router>
  );
}

额外优化建议

  1. 确认Login.js中token的解构逻辑:如果后端返回的是res.data.token(而非res.data.token.token),需要修正为const token = res.data.token;,避免因解构错误导致token未正确存入localStorage。
  2. 可在Login的handleSubmit中添加错误提示,比如当后端返回登录失败时,给用户显示对应的错误信息,提升体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 18:55:32