You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Router v6路由权限重定向及useNavigate上下文报错咨询

解决方案:React Router v6 登录状态路由重定向与上下文报错处理

核心问题分析

你遇到的useNavigate()只能在<Router>组件上下文中使用报错,本质是useNavigate钩子必须在被直接/间接包裹的组件内调用,而路由守卫逻辑如果脱离Router上下文就会触发该错误。同时要实现两个路由规则:

  • 未登录用户访问受保护路由 → 重定向至/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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 03:15:22