React项目中如何通过useRoutes hook实现Private Route私有路由
React 中使用 useRoutes 实现 Private Route 私有路由方案
react-router-dom v6 版本的useRoutes钩子本身不直接提供私有路由配置项,我们可以通过权限包装组件结合路由表配置实现,步骤如下:
1. 编写权限校验包装组件
这个组件的核心逻辑是拦截路由渲染请求,判断当前用户是否有访问权限,无权限则重定向到对应页面。
import { Navigate, useLocation } from 'react-router-dom'; /** * 路由权限包装组件 * @param children 实际要渲染的路由元素 * @param allowedRoles 可选,允许访问的角色列表,用于角色级权限控制 */ const RequireAuth = ({ children, allowedRoles }) => { // 替换为你项目实际的鉴权逻辑:可以从localStorage、Context、Redux等位置取登录态、用户信息 const token = localStorage.getItem('access_token'); const userInfo = JSON.parse(localStorage.getItem('user_info') || '{}'); const location = useLocation(); // 未登录:重定向到登录页,同时记录当前访问路径,登录成功后可直接跳回原页面 if (!token) { return <Navigate to="/login" state={{ from: location.pathname }} replace />; } // 配置了角色限制但当前用户角色不匹配:重定向到403无权限页 if (allowedRoles?.length && !allowedRoles.includes(userInfo.role)) { return <Navigate to="/403" replace />; } // 校验通过:渲染实际路由内容 return children; };
2. 结合 useRoutes 配置路由表
在路由配置中,所有需要权限控制的路由,直接用RequireAuth组件包裹对应的路由元素即可。
import { useRoutes } from 'react-router-dom'; // 引入页面组件 import Home from './pages/Home'; import Login from './pages/Login'; import UserCenter from './pages/UserCenter'; import AdminPanel from './pages/AdminPanel'; import NotFound from './pages/NotFound'; import NoPermission from './pages/NoPermission'; const AppRoutes = () => { const routeElements = useRoutes([ // 公开路由 { path: '/', element: <Home /> }, { path: '/login', element: <Login /> }, { path: '/403', element: <NoPermission /> }, // 需登录才能访问的路由 { path: '/user/center', element: ( <RequireAuth> <UserCenter /> </RequireAuth> ) }, // 需登录+管理员角色才能访问的路由 { path: '/admin', element: ( <RequireAuth allowedRoles={['admin', 'super_admin']}> <AdminPanel /> </RequireAuth> ) }, // 404匹配 { path: '*', element: <NotFound /> } ]); return routeElements; }; export default AppRoutes;
3. 根组件挂载路由
在应用根组件中用路由容器包裹路由配置即可生效:
import { BrowserRouter } from 'react-router-dom'; import AppRoutes from './AppRoutes'; function App() { return ( <BrowserRouter> {/* 其他全局组件比如全局提示、导航栏可以放这里 */} <AppRoutes /> </BrowserRouter> ); } export default App;
注意事项
- 嵌套路由场景下,只需要在父级路由用
RequireAuth包裹,所有子路由会自动继承权限校验,不需要重复包装 Navigate组件务必加replace属性,避免重定向后用户点击浏览器返回键再次进入重定向逻辑,造成体验问题- 鉴权逻辑不要只写在前端,后端接口必须同步做权限校验,前端路由拦截仅用于优化用户体验,无法替代后端鉴权
内容的提问来源于stack exchange,提问作者Atik Hasan
相关产品推荐
相关产品推荐

