React Router中已登录用户访问登录页重定向至首页的实现及路由跳转冲突问题解决
这个问题我之前也碰到过,核心冲突就是登录完成后的跳转被RestrictedPublicRoute的全局重定向给拦截了。其实只要加个简单的条件判断,区分用户是主动访问登录页,还是从受保护路由跳转过来完成登录的,就能完美解决。
解决方案:修改RestrictedPublicRoute的判断逻辑
修改你的RestrictedPublicRoute组件,在判断token存在的同时,检查当前登录页的跳转来源——也就是location.state里是否带有from字段(这个字段是你的ProtectedRoute重定向时设置的)。只有当用户主动访问登录页(没有from标记)且已登录时,才触发重定向到首页;如果是从受保护路由跳转过来的登录流程,即使登录后token存在,也不拦截后续的跳转。
修改后的代码:
export const RestrictedPublicRoute = () => { const { token } = useAuth() const location = useLocation() // 仅在已登录且非受保护路由重定向过来的情况下,重定向到首页 if (token && !location.state?.from) { return <Navigate to="/" replace /> } return <Outlet /> }
各场景逻辑验证
场景1:未登录访问受保护路由
ProtectedRoute会把用户重定向到/login,并在state中带上from(比如/dashboard)。此时token不存在,RestrictedPublicRoute正常渲染登录组件。用户登录后,token变为存在,但因为location.state.from存在,组件不会触发重定向,登录页里的navigate(origin)会顺利跳转到用户原本想访问的/dashboard。场景2:已登录主动访问登录页
不管是地址栏输入/login,还是点击登录链接,此时location.state里没有from字段,token存在,RestrictedPublicRoute会立即重定向到首页,符合需求。场景3:未登录直接访问登录页
token不存在,RestrictedPublicRoute正常渲染登录组件,无任何问题。
这样就彻底解决了跳转冲突的问题,既保留了登录后返回原路径的功能,又实现了已登录用户禁止访问登录页的需求。
内容的提问来源于stack exchange,提问作者vance

