React Router注册页面路由配置与登录权限跳转异常修复
解决方案
核心思路
把路由跳转逻辑从AuthContext的全局监听中剥离,改用路由守卫组件精细化控制页面访问权限:
- 已登录用户:仅能访问
/main,访问登录/注册页时自动跳转至/main - 未登录用户:可自由访问
/(登录)和/registration(注册),访问/main时自动跳转至登录页
步骤1:修改AuthContext.js
移除全局强制跳转逻辑,仅保留用户状态监听,同时添加清理订阅逻辑避免内存泄漏:
const AuthContext = React.createContext(); export const AuthProvider = ({children}) => { const [loading, setLoading] = useState(true); const [user, setUser] = useState(null); useEffect(() => { const unsubscribe = onAuthStateChanged(app, (user) => { setUser(user); setLoading(false); }); return unsubscribe; }, []); const value = {user}; return ( <AuthContext.Provider value={value}> {!loading && children} </AuthContext.Provider> ); } // 自定义Hook,简化组件获取用户状态的操作 export const useAuth = () => React.useContext(AuthContext);
步骤2:创建路由守卫组件
新建两个组件分别管控不同权限的路由:
PrivateRoute.js(仅登录用户可访问)
import { Navigate, Outlet } from 'react-router-dom'; import { useAuth } from './AuthContext'; export const PrivateRoute = () => { const { user } = useAuth(); return user ? <Outlet /> : <Navigate to="/" />; };
PublicRoute.js(仅未登录用户可访问)
import { Navigate, Outlet } from 'react-router-dom'; import { useAuth } from './AuthContext'; export const PublicRoute = () => { const { user } = useAuth(); return user ? <Navigate to="/main" /> : <Outlet />; };
步骤3:重构App.js路由结构
将所有路由统一纳入AuthProvider管理,用守卫组件包裹对应路由:
import { Router, Routes, Route } from 'react-router-dom'; import { AuthProvider } from './AuthContext'; import { PrivateRoute } from './PrivateRoute'; import { PublicRoute } from './PublicRoute'; import Main from './Main'; import Login from './Login'; import Registration from './Registration'; function App() { return ( <div style={{fontFamily: 'Avenir'}}> <Router> <AuthProvider> <Routes> {/* 已登录用户专属路由 */} <Route element={<PrivateRoute />}> <Route path="/main" element={<Main/>}/> </Route> {/* 未登录用户专属路由 */} <Route element={<PublicRoute />}> <Route path="/" element={<Login/>}/> <Route path="/registration" element={<Registration/>}/> </Route> </Routes> </AuthProvider> </Router> </div> ); }
步骤4:优化Login.js跳转方式
将原生<a>标签替换为React Router的<Link>,避免页面刷新:
import { Link } from 'react-router-dom'; export function Login() { //... 原有登录逻辑 return( //... 原有登录表单 <Link to="/registration"><h2>Registration</h2></Link> ); }
效果验证
- 未登录状态:
/和/registration可正常访问,访问/main自动跳转至登录页 - 登录状态:
/main正常访问,访问/或/registration自动跳转至/main
内容的提问来源于stack exchange,提问作者alex758
相关产品推荐
相关产品推荐

