如何用React-Router实现组件加载权限校验,修复URL跳转无权限加载问题
React-Router 权限校验修复方案:拦截无权限直接访问URL
问题根源
当前权限校验逻辑后置到了组件渲染阶段,导致直接访问无权限URL时,路由已匹配并开始加载目标组件,之后才触发权限跳转,因此组件仍会被加载。需要将校验逻辑前置到路由匹配后的组件渲染环节,确保无权限时直接跳转,不加载目标组件。
修复方案
1. 自定义权限路由组件(ProtectedRoute)
整合权限校验、Suspense 包裹逻辑以及用户状态加载判断,将所有校验逻辑前置:
import { useContext, Suspense } from 'react'; import { Navigate, useLocation } from 'react-router-dom'; import { UserContext } from './UserContext'; import LoadingSpinner from './LoadingSpinner'; // 自定义加载占位组件 const ProtectedRoute = ({ element, screenKey, fallback = <LoadingSpinner /> }) => { const { availableScreens, isLoading } = useContext(UserContext); const location = useLocation(); // 用户权限信息未加载完成时,显示加载状态 if (isLoading) { return fallback; } // 校验当前页面权限 const hasPermission = availableScreens.includes(screenKey); if (hasPermission) { // 有权限则用Suspense包裹组件,保留原有懒加载/代码分割能力 return <Suspense fallback={fallback}>{element}</Suspense>; } else { // 无权限直接跳转到首页,可携带原路径用于后续处理(可选) return <Navigate to="/" state={{ from: location }} replace />; } }; export default ProtectedRoute;
2. 替换原有路由配置
将需要权限校验的路由,用自定义的ProtectedRoute替代原生Route,传入对应页面的权限标识screenKey:
import { Routes, Route } from 'react-router-dom'; import ProtectedRoute from './ProtectedRoute'; import Home from './Home'; // 懒加载组件示例 const Dashboard = React.lazy(() => import('./Dashboard')); const Settings = React.lazy(() => import('./Settings')); function AppRoutes() { return ( <Routes> <Route path="/" element={<Home />} /> {/* 权限校验路由 */} <Route path="/dashboard" element={<ProtectedRoute screenKey="dashboard" element={<Dashboard />} />} /> <Route path="/settings" element={<ProtectedRoute screenKey="settings" element={<Settings />} />} /> {/* 404路由 */} <Route path="*" element={<Navigate to="/" replace />} /> </Routes> ); } export default AppRoutes;
3. 注意事项
screenKey必须与UserContext中availableScreens的权限标识完全一致,确保校验准确性。- 新增
isLoading状态判断,避免用户权限信息未加载完成时误跳转,提升体验。 - 保留了Suspense的懒加载逻辑,与原有代码分割需求完全兼容。
内容的提问来源于stack exchange,提问作者ganesh kaspate
相关产品推荐
相关产品推荐

