React Router v6路由权限重定向及useNavigate上下文报错咨询
解决方案:React Router v6 登录状态路由重定向与上下文报错处理
核心问题分析
你遇到的useNavigate()只能在<Router>组件上下文中使用报错,本质是useNavigate钩子必须在被
- 未登录用户访问受保护路由 → 重定向至
/login - 已登录用户访问
/login→ 重定向至/
步骤1:封装路由守卫组件
React Router v6推荐用Outlet(渲染子路由内容)和Navigate(重定向)来实现路由守卫,避免直接在路由配置中调用useNavigate。
受保护路由组件(ProtectedRoute)
用于拦截未登录用户访问需要权限的页面:
import { Navigate, Outlet } from 'react-router-dom'; // 接收登录状态作为props const ProtectedRoute = ({ isAuthenticated }) => { // 未登录则重定向到登录页 if (!isAuthenticated) { return <Navigate to="/login" replace />; } // 已登录则渲染子路由内容 return <Outlet />; }; export default ProtectedRoute;
公开路由组件(PublicRoute)
用于拦截已登录用户访问登录页:
import { Navigate, Outlet } from 'react-router-dom'; const PublicRoute = ({ isAuthenticated }) => { // 已登录则重定向到首页 if (isAuthenticated) { return <Navigate to="/" replace />; } // 未登录则渲染登录页内容 return <Outlet />; }; export default PublicRoute;
步骤2:配置路由结构
确保整个路由系统被<Router>(如BrowserRouter)包裹,然后用上面的守卫组件嵌套路由:
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import { useState } from 'react'; import ProtectedRoute from './ProtectedRoute'; import PublicRoute from './PublicRoute'; import Home from './Home'; import Login from './Login'; import Dashboard from './Dashboard'; function App() { // 这里用useState模拟登录状态,实际项目可替换为Redux/Context等状态管理 const [isAuthenticated, setIsAuthenticated] = useState(false); return ( <Router> <Routes> {/* 公开路由组:已登录用户访问/login会被重定向 */} <Route element={<PublicRoute isAuthenticated={isAuthenticated} />}> <Route path="/login" element={<Login setIsAuthenticated={setIsAuthenticated} />} /> </Route> {/* 受保护路由组:未登录用户访问会被重定向到/login */} <Route element={<ProtectedRoute isAuthenticated={isAuthenticated} />}> <Route path="/" element={<Home />} /> <Route path="/dashboard" element={<Dashboard />} /> </Route> {/* 兜底路由:匹配不到的路径重定向到首页 */} <Route path="*" element={<Navigate to="/" replace />} /> </Routes> </Router> ); } export default App;
步骤3:登录组件中正确使用useNavigate
在登录组件内(已被Router包裹)调用useNavigate,完成登录后的跳转:
import { useNavigate } from 'react-router-dom'; const Login = ({ setIsAuthenticated }) => { const navigate = useNavigate(); const handleLogin = () => { // 模拟登录接口请求,成功后更新登录状态 setIsAuthenticated(true); // 跳转至首页 navigate('/'); }; return ( <div> <h2>登录页</h2> <button onClick={handleLogin}>登录</button> </div> ); }; export default Login;
关键注意事项
- 所有调用
useNavigate的组件必须处于<Router>的上下文范围内,不能在Router外层组件中使用 - 用
Navigate组件替代直接在路由配置中调用useNavigate,避免上下文错误 - 登录状态的管理(如从localStorage读取、接口验证)可根据实际项目调整,核心是将状态传递给路由守卫组件
内容的提问来源于stack exchange,提问作者Sahil Karn
相关产品推荐
相关产品推荐

