React 18:如何正确实现路由守卫(PrivateRoute)功能?
问题解决:React Router v6路由守卫报错处理
你遇到的错误核心是React Router v6的路由规则限制:Route组件必须直接作为Routes的子元素,不能在其他组件内部返回Route后嵌套使用。你的PrivateRoute当前返回了Route,但又被当作element传给另一个Route,导致Route被直接渲染(而非作为Routes的子节点),触发报错。
正确的路由守卫实现方式
重构PrivateRoute为权限校验包装组件,不再返回Route,而是根据登录状态渲染目标组件或跳转登录页:
function PrivateRoute({ children }) { const isAuthenticated = localStorage.getItem('token'); // 未登录建议跳转到公开的登录页,避免死循环 return isAuthenticated ? children : <Navigate to="/" />; }
修正App中的路由结构
去掉冗余的嵌套Route,直接用PrivateRoute包裹需要保护的页面组件,作为Route的element值:
function App() { return ( <div className="App"> <header className="App-header"> <Router> <Fragment> <MainTemplate /> <Routes> <Route exact path='/' element={<Login />} /> {/* 受保护路由直接用PrivateRoute包裹目标组件 */} <Route exact path='/products' element={<PrivateRoute><Products /></PrivateRoute>} /> <Route exact path='/product/:id' element={<PrivateRoute><Product /></PrivateRoute>} /> <Route exact path='/add-product' element={<PrivateRoute><AddProduct /></PrivateRoute>} /> <Route exact path='/edit-product/:id' element={<PrivateRoute><UpdateProduct /></PrivateRoute>} /> <Route exact path='/orders' element={<PrivateRoute><Orders /></PrivateRoute>} /> <Route exact path='/edit-order/:id' element={<PrivateRoute><UpdateOrder /></PrivateRoute>} /> <Route exact path='/:category' element={<PrivateRoute><Category /></PrivateRoute>} /> </Routes> </Fragment> </Router> </header> </div> ); }
补充说明
- React Router v6彻底简化了路由嵌套逻辑,
Route的嵌套仅用于多段路径的布局场景(配合Outlet组件),普通的权限保护不需要嵌套路由。 - 注意登录状态跳转逻辑:如果未登录时跳转到
/products这类受保护路由,会触发无限跳转循环,建议跳转到公开的登录页/。
内容的提问来源于stack exchange,提问作者JDev
相关产品推荐
相关产品推荐

