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

React Router实现已登录用户禁止访问登录页的问题

问题解决:已登录用户访问登录页自动重定向首页

问题现状

已认证用户访问 /login 页面时,仍能正常进入登录页,无法自动跳转到首页。尝试修改 PrivateRoute 组件后问题未解决。

问题原因

  1. 当前 /login 路由未挂载任何路由守卫组件,直接渲染 Login 组件,导致已登录用户无拦截逻辑
  2. 修改后的 PrivateRoute 逻辑顺序错误:先判断user?.email存在就返回children,后续判断已登录且路径为/login的代码永远不会执行

解决方案

方案1:创建公共路由守卫(推荐)

新增一个 PublicRoute 组件,专门处理已登录用户禁止访问的公开页面(如登录、注册页):

// PublicRoute.jsx
import { useContext } from "react";
import { AuthContext } from "../providers/AuthProvider";
import { Navigate, useLocation } from "react-router-dom";

const PublicRoute = ({ children }) => {
  const { user, loading } = useContext(AuthContext);
  const location = useLocation();

  if (loading) {
    return <progress className="progress w-full"></progress>;
  }

  // 已登录用户访问登录/注册页,直接重定向到首页
  if (user?.email && (location.pathname === "/login" || location.pathname === "/signup")) {
    return <Navigate to="/" replace />;
  }

  return children;
};

export default PublicRoute;

在路由配置中,给 /login 和 /signup 路由挂载这个组件:

// route.jsx
// 导入新增的PublicRoute
import PublicRoute from "./PublicRoute";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Main></Main>,
    children: [
      {
        path: "/",
        element: <Home></Home>,
      },
      {
        path: "/login",
        element: (
          <PublicRoute>
            <Login></Login>
          </PublicRoute>
        ),
      },
      {
        path: "/signup",
        element: (
          <PublicRoute>
            <SignUp></SignUp>
          </PublicRoute>
        ),
      },
      // 其他私有路由保持不变
      {
        path: "/bookings",
        element: (
          <PrivateRoute>
            <Bookings></Bookings>
          </PrivateRoute>
        ),
      },
      {
        path: "/services/:id",
        element: <PrivateRoute><Checkout></Checkout></PrivateRoute>,
        loader: ({ params }) =>
          fetch(`http://localhost:5000/services/${params.id}`),
      },
    ],
  },
]);

方案2:直接在Login组件内处理重定向

如果不想新增组件,可以在 Login 组件内部判断用户状态:

// Login.jsx
import { useContext } from "react";
import { AuthContext } from "../providers/AuthProvider";
import { Navigate } from "react-router-dom";

const Login = () => {
  const { user, loading } = useContext(AuthContext);

  if (loading) {
    return <progress className="progress w-full"></progress>;
  }

  // 已登录直接重定向
  if (user?.email) {
    return <Navigate to="/" replace />;
  }

  // 原登录页面逻辑
  return (
    // ...你的登录表单代码
  );
};

export default Login;

说明

方案1更符合路由守卫的职责分离原则,将路由权限逻辑集中在守卫组件中,便于维护和扩展;方案2适合快速修改,逻辑直接在页面组件内处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:17:12