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

React路由报错:Routes子组件需为Route,如何修复ProtectedRoute重定向?

React Router 受保护路由重定向错误解决方法

问题场景

我有一个React项目,主组件通过路由服务渲染路由,希望实现:主页、404页、登录页对所有用户开放,部分页面仅允许已登录用户访问。为此自定义了ProtectedRoute组件,意图在未登录用户访问受保护页面时重定向到登录页,但运行时出现以下报错:

router.ts:5 Uncaught Error: [ProtectedRoute] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
    at invariant (router.ts:5:1)

现有代码

主组件

const App: React.FC = () => {
    return <BaseLayout>{RoutingService.getRoutes()}</BaseLayout>;
}

export default App;

路由服务

class RoutingService {
    static getRoutes = (): React.ReactNode => {
        return (
            <Routes>
                <Route key={makeRandomKey()} path={PATHS.ROOT_PATH} element={<MainPage/>}/>
                <Route key={makeRandomKey()} path={PATHS.AUTH_PATH} element={<LoginPage/>}/>
                <Route key={makeRandomKey()} path={PATHS.NOT_FOUND_PATH} element={<UnderConstructPage/>}/>
                <ProtectedRoute path={PATHS.SEARCH_HISTORY_PATH} element={<SearchHistoryPage/>}/>
                <ProtectedRoute path={PATHS.USER_CABINET_PATH} element={<UserCabinetPage/>}/>
            </Routes>
        );
    };
}

export default RoutingService;

现有ProtectedRoute组件

interface ProtectedRouteProps {
    path: string;
    element: React.ReactNode;
}

const ProtectedRoute: React.FC<ProtectedRouteProps> = ({path, element}) => {
    const isAuthenticated: boolean = useSelector((state: RootState) => !!state.user.userData?.auth?.token);

    return isAuthenticated ?
        <Route path={path} element={element}/> : <> <Navigate to="/auth" replace/></> ;
};

export default ProtectedRoute;

错误原因

React Router的<Routes>组件仅接受<Route>或<React.Fragment>作为直接子元素,而当前ProtectedRoute既不是<Route>也不是合法的直接子元素,因此触发报错。

正确实现方式

修改ProtectedRoute组件

将ProtectedRoute改为路由元素的包装器,不再返回<Route>组件:

interface ProtectedRouteProps {
    children: React.ReactNode;
}

const ProtectedRoute: React.FC<ProtectedRouteProps> = ({children}) => {
    const isAuthenticated: boolean = useSelector((state: RootState) => !!state.user.userData?.auth?.token);

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

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

export default ProtectedRoute;

更新路由服务

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

class RoutingService {
    static getRoutes = (): React.ReactNode => {
        return (
            <Routes>
                <Route key={makeRandomKey()} path={PATHS.ROOT_PATH} element={<MainPage/>}/>
                <Route key={makeRandomKey()} path={PATHS.AUTH_PATH} element={<LoginPage/>}/>
                <Route key={makeRandomKey()} path={PATHS.NOT_FOUND_PATH} element={<UnderConstructPage/>}/>
                <Route 
                    key={makeRandomKey()} 
                    path={PATHS.SEARCH_HISTORY_PATH} 
                    element={<ProtectedRoute><SearchHistoryPage/></ProtectedRoute>}
                />
                <Route 
                    key={makeRandomKey()} 
                    path={PATHS.USER_CABINET_PATH} 
                    element={<ProtectedRoute><UserCabinetPage/></ProtectedRoute>}
                />
            </Routes>
        );
    };
}

export default RoutingService;

核心逻辑说明

  • 让ProtectedRoute作为<Route>的element值,完全符合<Routes>对直接子元素的要求。
  • 组件内部根据登录状态,决定渲染受保护页面还是执行重定向逻辑,实现权限控制的核心需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 02:12:53