React Router v6 Route组件渲染Navigate实现受保护路由报错
问题根源
你的报错核心原因有两个:
- 类型依赖版本不匹配:你安装的
@types/react-router-dom是v5版本,但实际使用的react-router-dom是v6版本,v5的类型定义无法正确识别v6的组件,导致TypeScript误判Navigate的使用场景。 - 虽然你的
ProtectedRoute写法本身符合v6规范,但类型冲突让编译器错误地认为Navigate被直接作为<Routes>的子组件。
解决方案
第一步:修复类型依赖冲突
卸载v5版本的@types/react-router-dom,因为React Router v6本身已经内置了完整的类型定义,不需要额外安装第三方类型包:
npm uninstall @types/react-router-dom # 或使用yarn yarn remove @types/react-router-dom
第二步:调整ProtectedRoute实现(两种可选方式)
方式一:保持原有路由结构,优化组件逻辑
修正后的ProtectedRoute组件,增加加载状态处理(避免auth为undefined时的异常):
import { Navigate } from 'react-router-dom'; interface ProtectedRouteProps { auth: boolean | undefined; children: React.ReactNode; } const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ children, auth }) => { // 处理认证状态未加载完成的情况 if (auth === undefined) { return <div>加载中...</div>; } return auth ? children : <Navigate to={NOT_APPROVED_PATH} replace />; };
方式二:使用React Router v6的嵌套路由规范(推荐)
这种写法更贴合v6的路由设计理念,将受保护路由统一包裹:
import { Navigate, Outlet } from 'react-router-dom'; interface ProtectedRouteProps { auth: boolean | undefined; } const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ auth }) => { if (auth === undefined) { return <div>加载中...</div>; } // 已认证则渲染子路由(通过Outlet),否则跳转 return auth ? <Outlet /> : <Navigate to={NOT_APPROVED_PATH} replace />; }; // 路由配置示例 <Router> <Routes> {/* 所有需要保护的路由都放在这个包裹路由下 */} <Route element={<ProtectedRoute auth={customer?.isApproved} />}> <Route path={DASHBOARD_PATH} element={<ScreensHome />} /> {/* 可以添加更多受保护的子路由 */} </Route> {/* 未认证跳转的目标路由 */} <Route path={NOT_APPROVED_PATH} element={<NotApprovedScreen />} /> </Routes> </Router>
验证
完成以上步骤后,重新启动项目,类型错误和路由报错应该会消失,受保护路由的逻辑也能正常工作。
内容的提问来源于stack exchange,提问作者Vitaliy Martiniuk
相关产品推荐
相关产品推荐

