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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 18:15:08