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

React Route组件渲染报错:鉴权包装组件的修复方案

React Router v6 登录鉴权报错解决及正确实现

错误原因

React Router v6 对 <Routes> 的直接子组件有严格限制,仅允许 <Route> 或 <React.Fragment> 作为其子元素。你写的 <PrivateRoute> 是自定义组件,直接放在 <Routes> 下触发了这个报错。另外,旧版(v5)中通过自定义Route包装组件的写法在v6中不再适用,v6采用基于element的路由模型,鉴权逻辑需要嵌入到路由的element属性中。

正确实现步骤

1. 重构 PrivateRoute 为元素包装组件

把原来返回 <Route> 的 PrivateRoute 改成纯鉴权逻辑组件,仅负责校验用户状态,通过则渲染子元素,不通过则重定向到登录页:

import { Navigate } from 'react-router-dom';
import { FC, ReactNode } from 'react';
import { usePermission } from './your-permission-path'; // 替换为你的usePermission实际路径

interface PrivateRouteProps {
  children: ReactNode;
}

const PrivateRoute: FC<PrivateRouteProps> = ({ children }) => {
  const { userIsAuthenticated } = usePermission();

  // 未认证则重定向,replace属性避免回退栈保留当前无效路由
  if (!userIsAuthenticated()) {
    return <Navigate to="/login" replace />;
  }

  // 已认证则渲染受保护的页面内容
  return <>{children}</>;
};

export default PrivateRoute;

2. 调整路由服务代码

在 <Routes> 中直接使用官方 <Route> 组件,私有路由的element用 PrivateRoute 包裹需要保护的页面内容,公开路由直接渲染即可:

import { Router, Routes, Route, Navigate } from 'react-router-dom';
import { FC } from 'react';
import { SecurityProvider } from './your-security-provider-path'; // 替换为实际路径
import PrivateRoute from './PrivateRoute';
import { privateRoutes, publicRoutes } from './your-routes-config-path'; // 替换为实际路径
import Layout from './Layout';
import BaseLayout from './BaseLayout';

export const RouterService: FC = () => {
  return (
    <Router>
      <SecurityProvider>
        <Routes>
          {/* 渲染私有路由 */}
          {privateRoutes.map((route, index) => (
            <Route
              key={index}
              path={route.path}
              element={
                <PrivateRoute>
                  <Layout>
                    <route.element />
                  </Layout>
                </PrivateRoute>
              }
            />
          ))}

          {/* 渲染公开路由 */}
          {publicRoutes.map((route, index) => (
            <Route
              key={index}
              path={route.path}
              element={
                <BaseLayout>
                  <route.element />
                </BaseLayout>
              }
            />
          ))}

          {/* 匹配所有未定义路由,重定向到登录页 */}
          <Route path="*" element={<Navigate to="/login" replace />} />
        </Routes>
      </SecurityProvider>
    </Router>
  );
};

3. 可选:扩展细粒度权限校验

如果需要基于权限的访问控制,可以给 PrivateRoute 添加权限校验逻辑:

// 扩展后的PrivateRoute
interface PrivateRouteProps {
  children: ReactNode;
  requiredPermission?: string;
}

const PrivateRoute: FC<PrivateRouteProps> = ({ children, requiredPermission }) => {
  const { userIsAuthenticated, hasPermission } = usePermission();

  if (!userIsAuthenticated()) {
    return <Navigate to="/login" replace />;
  }

  // 校验指定权限,无权限则重定向到403页面
  if (requiredPermission && !hasPermission(requiredPermission)) {
    return <Navigate to="/403" replace />;
  }

  return <>{children}</>;
};

使用时只需传入权限参数:

<Route
  path="/users"
  element={
    <PrivateRoute requiredPermission="user:view">
      <Layout>
        <UsersPage />
      </Layout>
    </PrivateRoute>
  }
/>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 05:15:57