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

React Router报错:ProtectedRoute非Route组件,无法作为Routes子元素

解决React Router v6中ProtectedRoute报错:<ProtectedRoute /> is not a <Route> component

错误原因

  1. React Router v6 强制要求<Routes>的直接子元素必须是<Route>或<React.Fragment>,自定义组件不能直接作为子节点(即便组件内部返回<Route>,也不符合v6的路由配置规范)
  2. v6 移除了<Route>的render属性,统一使用element属性传递要渲染的组件,你的代码中仍在使用render,这也是报错的核心诱因之一

修复方案

方案一:将ProtectedRoute重构为权限校验容器组件

这种方式更贴合v6的设计思路,把权限校验逻辑封装成容器,包裹需要保护的页面组件:

1. 修改ProtectedRoute组件

import { Navigate, useLocation } from 'react-router-dom';

const adminUsers = [
  {username:'admin', password:'admin'}
  // 其他管理员用户
];

const ProtectedRoute = ({ children }) => {
  const location = useLocation();
  const currentUser = localStorage.getItem('user');
  const isAdmin = adminUsers.some(user => user.username === currentUser);

  // 校验通过则渲染子组件,否则重定向到登录页
  if (currentUser && isAdmin) {
    return children;
  }
  return <Navigate to="/login" replace state={{ from: location }} />;
};

export default ProtectedRoute;

2. 修改App中的路由配置

在<Route>的element属性中用ProtectedRoute包裹需要保护的页面:

import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Home from './pages/Home';
import Login from './pages/Login';
import Register from './pages/Register';
import BookingCar from './pages/BookingCar';
import AddCar from './pages/AddCar';
import Admin from './pages/Admin';
import EditCar from './pages/EditCar';
import ProtectedRoute from './components/ProtectedRoute';
import UserBookings from './pages/userBookings';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/login" element={<Login />} />
        <Route path="/register" element={<Register />} />
        
        {/* 受保护路由配置 */}
        <Route path="/booking/:carid" element={
          <ProtectedRoute>
            <BookingCar />
          </ProtectedRoute>
        } />
        <Route path="/userbookings" element={
          <ProtectedRoute>
            <UserBookings />
          </ProtectedRoute>
        } />
        <Route path="/addcar" element={
          <ProtectedRoute>
            <AddCar />
          </ProtectedRoute>
        } />
        <Route path="/editcar/:carid" element={
          <ProtectedRoute>
            <EditCar />
          </ProtectedRoute>
        } />
        <Route path="/admin" element={
          <ProtectedRoute>
            <Admin />
          </ProtectedRoute>
        } />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

方案二:让ProtectedRoute返回标准的Route组件

如果你想保留类似原写法的结构,可以让ProtectedRoute接收路由参数,返回符合v6规范的Route组件:

1. 修改ProtectedRoute组件

import { Navigate, Route, useLocation } from 'react-router-dom';

const adminUsers = [
  {username:'admin', password:'admin'}
  // 其他管理员用户
];

const ProtectedRoute = ({ path, element }) => {
  const location = useLocation();
  const currentUser = localStorage.getItem('user');
  const isAdmin = adminUsers.some(user => user.username === currentUser);

  return (
    <Route
      path={path}
      element={
        currentUser && isAdmin ? 
          element : 
          <Navigate to="/login" replace state={{ from: location }} />
      }
    />
  );
};

export default ProtectedRoute;

2. App中的路由配置可保持不变

此时原App路由写法能正常工作,因为ProtectedRoute内部返回的是标准<Route>组件,符合v6对<Routes>子元素的要求。

额外注意事项

  • 确保安装的是React Router v6版本,v5写法与v6差异较大
  • localStorage.getItem('user')获取的是字符串,要确保adminUsers中的username也是字符串类型,避免校验失败
  • 登录成功后,需正确将用户名存入localStorage.setItem('user', 'admin'),否则权限校验会不通过

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 20:43:24