React角色权限路由刷新重定向问题:如何阻塞应用至路由加载完成?
解决方案
问题根源是页面刷新时角色还未加载完成,但路由组件已开始渲染。此时userRoles为空或未定义,导致权限匹配的路由无法生成,最终触发通配符路由*的重定向逻辑。解决核心是在角色加载完成前,阻止路由初始化或通配符路由的匹配。
方案一:在App层完全阻塞路由渲染
直接在App.tsx中判断角色加载状态,加载完成前仅展示Loader,不渲染Router组件:
const App: React.FC = () => { const { loading } = useRoleBased(); // 从自定义hook获取加载状态 // 角色加载中时,只显示Loader if (loading) { return <Loader open backgroundColor="#ffffff" circleColor="primary" />; } // 角色加载完成后,渲染完整页面结构和路由 return ( <Box className={`mainSideBar ${openSideBar && 'openSideBar'}`}> <Router /> </Box> ); }; export default App;
这种方式从根源避免路由初始化,彻底解决重定向问题。
方案二:在权限路由组件中控制路由渲染
若想保留页面框架,可在RolesAuthRoute.tsx中判断角色是否已加载,未加载时不渲染任何路由(包括通配符重定向):
export function RolesAuthRoute({ routes }: { routes: IRoutes[] }) { const userRoles = useSelector((state: any) => state?.roles?.roles); // 判断角色数据是否已加载(避免初始空值导致误判) const isRolesLoaded = userRoles !== undefined; const isAllowed = ( allowedRoles: Roles[] | undefined, userRoles: string[]) => process.env.REACT_APP_ACTIVATE_ROLE_BASED_AUTH === 'false' || !allowedRoles || allowedRoles?.some((allowedRole) => userRoles?.includes(allowedRole) ); // 角色未加载时,不渲染任何路由(或返回加载占位组件) if (!isRolesLoaded) { return null; } return ( <Routes> {routes.map((route) => { if (isAllowed(route?.allowedRoles, userRoles)) return ( <Route path={route?.path} element={route?.element} key={route?.path} /> ); else return null; })} <Route path="*" element={<Navigate to="/" replace />} /> </Routes> ); }
这种方式保留页面框架,但阻止路由匹配逻辑执行,直到角色数据就绪。
注意事项
- 确保
useRoleBasedhook能正确返回loading状态(或明确判断角色是否加载完成),避免状态判断错误引发异常。 - 使用方案二时,需保证App层的Loader已覆盖页面,避免用户看到未就绪的空白结构。
内容的提问来源于stack exchange,提问作者Oussama Abouzid
相关产品推荐
相关产品推荐

