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

React受保护路由问题:登录后无法跳转至Dashboard

问题分析与解决方案

问题根源

核心问题在于:App组件初始化时一次性读取用户状态(getUser()),但登录设置Cookie后,App组件并未触发重新渲染,导致路由守卫使用的还是初始的未登录状态。因此首次登录跳转时会被拦截回登录页;而手动输入URL时,页面重新加载,App组件重新初始化,此时Cookie已存在,getUser()能正确读取角色信息,路由校验通过。

解决方案

需要让路由守卫的用户状态动态响应Cookie变化,而非仅在组件初始化时读取一次,以下是两种可行方案:


方案1:封装动态路由守卫组件

创建ProtectedSuperRoute组件,在组件内部实时检查用户状态,替代静态判断:

import React from "react";
import { Navigate, Outlet } from "react-router-dom";
import { getUser } from "./lib/jwtdecode";

function ProtectedSuperRoute() {
  const user = getUser();
  const is_super = user?.super === true;

  // 实时判断用户权限
  return is_super ? <Outlet /> : <Navigate to="/login" replace />;
}

export default ProtectedSuperRoute;

修改App组件的路由配置,使用该守卫组件:

import React from "react";
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
import DashboardLayout from "./components/layout/dashlayout";
import AdminDashboard from "./pages/admin/dashboard";
import PageNotFoundError from "./pages/404error";
import LoginPage from "./pages/auth/login";
import ListCompaniesPage from "./pages/admin/listcompanies";
import ListUsersPage from "./pages/admin/listusers";
import ProtectedSuperRoute from "./components/ProtectedSuperRoute";

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="*" element={<PageNotFoundError />} />
        <Route path="/" element={<Navigate to="/login" replace />} />
        <Route path="/login" element={<LoginPage />} />

        {/* 使用动态路由守卫 */}
        <Route element={<ProtectedSuperRoute />}>
          <Route element={<DashboardLayout />}>
            <Route path="/dashboard" element={<AdminDashboard />} />
            <Route path="/list-companies" element={<ListCompaniesPage />} />
            <Route path="/list-users" element={<ListUsersPage />} />
            {/* 其他路由 */}
          </Route>
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

export default App;

方案2:在App组件中监听Cookie变化,更新用户状态

若不想新增组件,可在App中用useState和useEffect监听Cookie变化,实时更新用户状态:

import React, { useState, useEffect } from "react";
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
import DashboardLayout from "./components/layout/dashlayout";
import AdminDashboard from "./pages/admin/dashboard";
import PageNotFoundError from "./pages/404error";
import LoginPage from "./pages/auth/login";
import ListCompaniesPage from "./pages/admin/listcompanies";
import ListUsersPage from "./pages/admin/listusers";
import { getUser } from "./lib/jwtdecode";
import Cookies from "js-cookie";

function App() {
  const [is_super, setIsSuper] = useState(false);

  // 监听Cookie变化,实时更新用户状态
  useEffect(() => {
    const updateUserStatus = () => {
      const user = getUser();
      setIsSuper(user?.super === true);
    };

    // 初始化执行一次
    updateUserStatus();

    // 定时检查Cookie变化
    const interval = setInterval(updateUserStatus, 500);
    return () => clearInterval(interval);
  }, []);

  return (
    <BrowserRouter>
      <Routes>
        <Route path="*" element={<PageNotFoundError />} />
        <Route path="/" element={<Navigate to="/login" replace />} />
        <Route path="/login" element={<LoginPage />} />

        <Route element={is_super ? <DashboardLayout /> : <Navigate to="/login" replace />}>
          <Route path="/dashboard" element={<AdminDashboard />} />
          <Route path="/list-companies" element={<ListCompaniesPage />} />
          <Route path="/list-users" element={<ListUsersPage />} />
          {/* 其他路由 */}
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

export default App;

为什么之前的延迟跳转无效?

你尝试的loginSuccessful状态更新仅触发LoginPage组件重新渲染,但App组件的用户状态并未更新,路由守卫依然使用初始的is_super=false判断,因此跳转仍会被拦截。只有让App组件或路由守卫组件实时读取最新的Cookie状态,才能解决问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 03:01:09