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

React自定义ProtectedRoute组件未渲染、token校验逻辑失效问题排查

问题根因排查与解决方案

1. 核心错误:违反React Router v6的路由声明规则

React Router v6要求所有<Route>组件必须是<Routes>组件的直接子节点,不能包裹在自定义组件内部。你当前的实现把<Route>放在ProtectedRoute的返回值中,再将<ProtectedRoute>作为<Routes>的子节点,会导致路由系统根本识别不到你在ProtectedRoute内声明的路由规则,ProtectedRoute本身也不会被路由逻辑触发执行,这就是为什么你看不到console输出、修改ProtectedRoute返回值完全不生效的核心原因。
你能正常访问受保护路径,大概率是你的App.tsx中存在冗余的路由声明,直接匹配到了对应路径,完全绕开了你写的鉴权逻辑。

2. 正确的ProtectedRoute实现方式

React Router v6的路由鉴权组件应该作为受保护页面的包装层,而非<Route>的包装层,参考实现如下:

// ProtectedRoute.tsx
import { Navigate } from 'react-router-dom';
import { useState, useLayoutEffect } from 'react';
import axios from 'axios';

const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
  // 初始设为null表示校验中,避免未完成校验时错误跳转
  const [hasValidToken, setHasValidToken] = useState<boolean | null>(null); 

  useLayoutEffect(() => {
    axios
      .get('http://localhost:5000/authorization', {
        withCredentials: true,
      })
      .then((response) => {
        setHasValidToken(true);
        console.log('valid token!');
      })
      .catch((error) => {
        if (error.response?.data?.message) {
          console.error(error.response.data.message);
        } else {
          console.error(`Error: ${error}`);
        }
        setHasValidToken(false);
      });
  }, []);

  // 校验中返回加载态
  if (hasValidToken === null) return <div>加载中...</div>;

  return hasValidToken ? children : <Navigate to="/login" replace />;
};

export default ProtectedRoute;

3. 路由配置调整

你遍历路由配置生成路由的逻辑需要修改为以下形式,将受保护的页面组件传入ProtectedRoute的children:

// App.tsx 中的路由声明部分
import { Routes, Route } from 'react-router-dom';
import ProtectedRoute from './common/components/ProtectedRoute';
import protectedRoutes from './config/protectedRoutes';
// 其他页面组件导入省略

function App() {
  return (
    <Routes>
      {/* 公共路由直接声明 */}
      <Route path="/login" element={<Login />} />
      {/* 受保护路由遍历生成 */}
      {protectedRoutes.map((route) => (
        <Route 
          key={route.path} 
          path={route.path} 
          element={
            <ProtectedRoute>
              {route.element}
            </ProtectedRoute>
          } 
        />
      ))}
    </Routes>
  );
}

4. 额外注意事项

  • 先检查App.tsx中是否有重复的路由声明,删除和受保护路径重合的冗余Route配置,避免绕开鉴权
  • 跳转登录页时添加replace属性,避免用户点击后退按钮回到鉴权页出现循环跳转
  • 如果需要适配路由切换时重新校验权限,可以把当前路由路径加入useLayoutEffect的依赖数组

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 22:06:05