React Router v6使用PrivateRoute出现Route需包裹在Routes内错误如何解决
错误成因排查
- 核心原因是你用了React Router v5的私有路由写法写v6版本的代码,v6有两个强制规则你没有遵守:
- 所有
<Route>组件必须是<Routes>组件的直接子节点,不允许在自定义组件内返回<Route>再放到<Routes>下,中间多了一层自定义组件包裹就会触发你遇到的报错 - v6的
<Route>已经废弃了component属性,统一使用element属性传入组件实例
- 所有
- 额外问题:你的项目存在两个入口冲突,
App.js用React18的createRoot渲染,app.js又用旧版render渲染同一个DOM节点,会导致逻辑混乱,先保留一个入口即可。
修复方案
1. 重写PrivateRoute.js
v6的私有路由应该写为组件包装器,不要返回<Route>:
import React from 'react'; import { Navigate } from 'react-router'; const PrivateRoute = ({ children }) => { const token = window.localStorage.getItem('token'); return token ? children : <Navigate to='/signin' replace /> } export default PrivateRoute;
2. 正确使用私有路由
在路由配置的element属性中用<PrivateRoute>包裹需要鉴权的组件即可,示例如下(以你的app.js路由配置为例):
import PrivateRoute from './PrivateRoute' // 引入你写的私有路由 render( <Router> <Routes> <Route path="/" element={<InsertUser />} /> {/* 需要鉴权的路由用PrivateRoute包一层 */} <Route path="/viewUsers" element={ <PrivateRoute> <ViewUsers /> </PrivateRoute> } /> <Route path="/viewUser/:id" element={ <PrivateRoute> <ViewUser /> </PrivateRoute> } /> </Routes> </Router>, document.getElementById("app") );
3. 其他代码问题修复
viewUsers.jsx中useState语法错误,修改为:const [tableData, setTableData] = useState([]);,初始值设为空数组,否则读取length属性会报错viewUsers.jsx中删除请求回调写法错误,修改为:
原写法会在请求发起时就立即执行alert,而非请求成功后执行const deleteData = (id) => { axios .delete("http://localhost:3000/api/user/delete/" + id) .then(() => alert("Deleted")); };- 代码中多处使用
window.location.href跳转,会刷新页面,建议替换为React Router提供的useNavigatehook实现无刷新跳转。
内容的提问来源于stack exchange,提问作者ShewaniPerera
相关产品推荐
相关产品推荐

