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

React TS实现路由守卫报错:GuardedRoute不是Route组件

解决方案:React Router v6 路由守卫报错处理

错误原因

React Router v6 对 <Routes> 的直接子节点有严格限制,必须是 <Route> 或 <React.Fragment> 组件。你自定义的 <GuardedRoute> 不属于这两类组件,直接作为 <Routes> 的子元素会触发该错误。


方案一:守卫组件包裹路由元素

修改 GuardedRoute.tsx,让它成为一个权限判断的包装组件,接收需要守卫的组件作为子元素,根据用户状态返回目标组件或跳转:

import { Navigate } from 'react-router-dom';
import { useUserInfo } from '../context/UserContext';
import type { ReactNode } from 'react';

export const GuardedRoute = ({ children }: { children: ReactNode }) => {
  const { userInfo } = useUserInfo();

  // 验证用户登录状态,已登录则渲染目标组件,否则跳转到首页
  return userInfo.id !== '' ? children : <Navigate to="/" replace />;
};

在 App.tsx 中,用 GuardedRoute 包裹需要权限验证的路由元素:

<BrowserRouter>
  <Nav></Nav>
  <div className="w-[100vw] fixed top-[50px] z-[100] flex flex-col">
    {ErrorMessages.map((message, index) => (
      <div className="w-[300px] h-[50px] mt-[10px] mx-auto bg-red-600/90 rounded-md grid place-content-center" key={index}>
        <p className="font-bold text-gray-200 text-center">{message}</p>
      </div>
    ))}
  </div>
  <Routes>
    <Route path="/" element={<Home />} />
    {/* 用GuardedRoute守卫需要权限的页面 */}
    <Route path="/profile/:select?" element={<GuardedRoute><Profile /></GuardedRoute>} />
    <Route path="/checkout" element={<GuardedRoute><CheckOut /></GuardedRoute>}/>
    <Route path="/register" element={<Register />} />
    <Route path="/login" element={<Login />} />
    <Route path="/browse" element={<Browse />} />
    <Route path="/product/:id" element={<Product />} />
    <Route path="/404" element={<PageNotFound />}/>
    <Route path="*" element={<Navigate to="/404" />}/>
  </Routes>
</BrowserRouter>

方案二:嵌套路由统一守卫(更整洁)

如果有多个需要权限验证的路由,可以用嵌套路由的方式,将守卫逻辑作为父路由的元素,统一管理:

修改 GuardedRoute.tsx,使用 <Outlet> 渲染子路由内容:

import { Navigate, Outlet } from 'react-router-dom';
import { useUserInfo } from '../context/UserContext';

export const GuardedRoute = () => {
  const { userInfo } = useUserInfo();

  // 用户未登录则跳转首页
  if (userInfo.id === '') {
    return <Navigate to="/" replace />;
  }

  // Outlet会自动渲染匹配的子路由组件
  return <Outlet />;
};

在 App.tsx 中,将需要守卫的路由作为 GuardedRoute 的子路由:

<BrowserRouter>
  <Nav></Nav>
  <div className="w-[100vw] fixed top-[50px] z-[100] flex flex-col">
    {ErrorMessages.map((message, index) => (
      <div className="w-[300px] h-[50px] mt-[10px] mx-auto bg-red-600/90 rounded-md grid place-content-center" key={index}>
        <p className="font-bold text-gray-200 text-center">{message}</p>
      </div>
    ))}
  </div>
  <Routes>
    <Route path="/" element={<Home />} />
    {/* 父路由统一处理权限验证,子路由为需要守卫的页面 */}
    <Route element={<GuardedRoute />}>
      <Route path="/profile/:select?" element={<Profile />} />
      <Route path="/checkout" element={<CheckOut />}/>
    </Route>
    <Route path="/register" element={<Register />} />
    <Route path="/login" element={<Login />} />
    <Route path="/browse" element={<Browse />} />
    <Route path="/product/:id" element={<Product />} />
    <Route path="/404" element={<PageNotFound />}/>
    <Route path="*" element={<Navigate to="/404" />}/>
  </Routes>
</BrowserRouter>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 01:58:28