React Router v6页面刷新跳转首页:如何保持当前页面路由
React Router v6条件路由刷新跳首页解决方案
问题根源
页面刷新时,Context中的UserType处于未初始化/空值状态,路由判断逻辑因拿不到有效用户类型,触发了默认跳转首页的逻辑。
具体解决方案
1. 增加加载状态,避免未初始化时误跳转
在用户Context中添加加载状态,确保用户类型数据加载完成前,不执行路由判断,而是显示加载组件。
UserContext示例代码:
import { createContext, useContext, useState, useEffect } from 'react'; const UserContext = createContext(); export function UserProvider({ children }) { const [userType, setUserType] = useState(null); const [isLoading, setIsLoading] = useState(true); useEffect(() => { // 从持久化存储(如localStorage)读取用户类型 const savedUserType = localStorage.getItem('userType'); if (savedUserType) { setUserType(savedUserType); } setIsLoading(false); }, []); // 用户类型变更时同步更新持久化存储 useEffect(() => { if (userType) { localStorage.setItem('userType', userType); } else { localStorage.removeItem('userType'); } }, [userType]); return ( <UserContext.Provider value={{ userType, setUserType, isLoading }}> {children} </UserContext.Provider> ); } export function useUser() { return useContext(UserContext); }
路由组件中处理加载状态:
import { Routes, Route, Navigate } from 'react-router-dom'; import { useUser } from './UserContext'; import Loading from './Loading'; import CompanyHome from './CompanyHome'; import DoctorHome from './DoctorHome'; import YourChildren from './YourChildren'; import Home from './Home'; function App() { const { userType, isLoading } = useUser(); // 加载完成前不渲染路由逻辑 if (isLoading) { return <Loading />; } return ( <Routes> <Route path="/" element={<Home />} /> <Route path="/company" element={userType === 'company' ? <CompanyHome /> : <Navigate to="/" />} /> <Route path="/doctor" element={userType === 'Doctor' ? <DoctorHome /> : <Navigate to="/" />} /> <Route path="/your-children" element={userType === 'children' ? <YourChildren /> : <Navigate to="/" />} /> <Route path="*" element={<Navigate to="/" />} /> </Routes> ); } export default App;
2. 封装路由守卫组件,统一权限判断
把权限判断逻辑封装成独立组件,让路由结构更清晰,避免重复代码。
路由守卫组件示例:
import { Navigate, useLocation } from 'react-router-dom'; import { useUser } from './UserContext'; import Loading from './Loading'; export function RequireAuth({ allowedUserTypes, children }) { const { userType, isLoading } = useUser(); const location = useLocation(); if (isLoading) { return <Loading />; } // 无有效用户类型或不在允许列表内,才跳转首页 if (!userType || !allowedUserTypes.includes(userType)) { return <Navigate to="/" state={{ from: location }} replace />; } return children; }
使用路由守卫的路由结构:
<Routes> <Route path="/" element={<Home />} /> <Route path="/company" element={ <RequireAuth allowedUserTypes={['company']}> <CompanyHome /> </RequireAuth> } /> <Route path="/doctor" element={ <RequireAuth allowedUserTypes={['Doctor']}> <DoctorHome /> </RequireAuth> } /> <Route path="/your-children" element={ <RequireAuth allowedUserTypes={['children']}> <YourChildren /> </RequireAuth> } /> <Route path="*" element={<Navigate to="/" />} /> </Routes>
内容的提问来源于stack exchange,提问作者Masir
相关产品推荐
相关产品推荐

