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

如何基于路由对象实现React Router v6的受保护路由?

实现React Router v6的受保护路由方案

嘿,我来帮你搞定React Router v6的受保护路由问题!针对你现有的路由数组,我们可以通过创建一个受保护路由组件来实现仅允许已登录用户访问指定页面的需求,具体步骤如下:

1. 创建受保护路由组件

首先,我们需要写一个ProtectedRoute组件,它的核心作用是检查用户登录状态:未登录时自动跳转到登录页,已登录则渲染目标组件。

import { Navigate } from 'react-router-dom';

// 自定义Hook:获取用户登录状态(你可以根据实际项目调整逻辑,比如从Context/Redux/localStorage取)
const useAuth = () => {
  // 示例:用localStorage判断是否登录,替换成你的实际判断逻辑
  const isLoggedIn = localStorage.getItem('currentUser') !== null;
  return { isLoggedIn };
};

// 受保护路由核心组件
const ProtectedRoute = ({ children }) => {
  const { isLoggedIn } = useAuth();

  if (!isLoggedIn) {
    // 未登录时跳转到登录页,同时记录当前路径,方便登录后跳转回来
    return <Navigate to="/login" replace state={{ from: window.location.pathname }} />;
  }

  // 已登录则渲染目标组件
  return children;
};

2. 修改你的路由数组

接下来,把需要保护的路由(比如/dashboard、/list)的element用ProtectedRoute包裹起来,公开路由(比如/)保持原样即可:

const routes = [
  { path: "/", element: <Component1 /> }, // 公开路由,无需登录即可访问
  { 
    path: "/dashboard", 
    element: (
      <ProtectedRoute>
        <Component1 /> {/* 这里替换成你的Dashboard组件 */}
      </ProtectedRoute>
    ) 
  },
  { 
    path: "/list", 
    element: (
      <ProtectedRoute>
        <Component2 />
      </ProtectedRoute>
    ) 
  },
  // 别忘了添加登录页路由(如果还没加的话)
  { path: "/login", element: <LoginComponent /> }
];

3. 登录页跳转逻辑优化

为了提升用户体验,登录成功后应该跳转到用户原本想要访问的页面,而不是固定首页。你可以在登录组件里这样处理:

import { useNavigate, useLocation } from 'react-router-dom';

const LoginComponent = () => {
  const navigate = useNavigate();
  const location = useLocation();
  // 获取登录前的目标路径,默认跳转到首页
  const from = location.state?.from || "/";

  const handleLogin = () => {
    // 这里写你的登录逻辑:比如调用登录API、存储用户信息到localStorage/state
    localStorage.setItem('currentUser', JSON.stringify({ id: 1, username: 'xxx' }));
    
    // 登录成功后跳转到之前的目标页面
    navigate(from, { replace: true });
  };

  return (
    <div>
      <h2>请登录</h2>
      {/* 这里可以添加用户名密码输入框 */}
      <button onClick={handleLogin}>登录</button>
    </div>
  );
};

4. 嵌套路由的适配(可选)

如果你的/dashboard下有嵌套子路由,比如/dashboard/settings,可以用Outlet来实现更简洁的嵌套保护:

// 修改ProtectedRoute组件,支持嵌套路由
const ProtectedRoute = () => {
  const { isLoggedIn } = useAuth();
  if (!isLoggedIn) {
    return <Navigate to="/login" replace state={{ from: window.location.pathname }} />;
  }
  // 用Outlet渲染子路由内容
  return <Outlet />;
};

// 路由数组调整为嵌套结构
const routes = [
  { path: "/", element: <Component1 /> },
  { 
    path: "/dashboard", 
    element: <ProtectedRoute />, // 父路由用ProtectedRoute保护所有子路由
    children: [
      { path: "", element: <DashboardHome /> }, // /dashboard
      { path: "settings", element: <DashboardSettings /> } // /dashboard/settings
    ]
  },
  { path: "/list", element: <ProtectedRoute><Component2 /></ProtectedRoute> },
  { path: "/login", element: <LoginComponent /> }
];

关键要点总结

  • ProtectedRoute的核心是登录状态判断,你可以根据项目的状态管理方案(Context、Redux、Zustand等)调整useAuth的逻辑
  • 使用Navigate组件的replace属性可以避免登录后点击返回按钮回到登录页
  • 通过state传递目标路径,能让用户登录后直接回到之前想要访问的页面,提升体验

内容的提问来源于stack exchange,提问作者cmoshe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:18:11