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

React Router v6保护路由问题:无法判断历史状态

问题分析与解决方案

你的问题核心是没有正确获取react-router提供的location对象,导致location.key始终为default。以下是具体原因和修正方案:

原因

你通过组件props接收的location和navigate并未被react-router的路由上下文正确注入,react-router v6中必须通过钩子(如useLocation、useNavigate)来获取路由相关的状态和方法,而非直接通过props传递(除非手动在路由配置中传递,但这不是推荐用法)。

修正后的ProtectedRoute组件

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

export const ProtectedRoute = ({ isAuthenticated, children }) => {
  const location = useLocation();
  const navigate = useNavigate();

  const hasPreviousState = location.key !== 'default';    
  if (isAuthenticated) {
    if (hasPreviousState) {
      console.log('previous state');
      navigate(-1);
    } else {
      console.log('no previous state');
      navigate('/');
    }    
    // 跳转后返回null,避免children不必要的渲染
    return null;
  }
  return children;
};

关键改进点

  1. 使用useLocation钩子获取当前路由的location对象,确保拿到正确的location.key值
  2. 使用useNavigate钩子获取导航方法,替代props传递的navigate
  3. 认证通过并执行跳转后返回null,避免先渲染children再跳转的问题

正确使用方式

在路由配置中用ProtectedRoute包裹需要保护的页面(如登录页):

import { Route, Routes } from 'react-router-dom';
import { ProtectedRoute } from './ProtectedRoute';
import LoginPage from './LoginPage';
import HomePage from './HomePage';

function App() {
  // 替换为你的实际认证状态判断逻辑
  const isAuthenticated = localStorage.getItem('token') !== null;

  return (
    <Routes>
      <Route path="/login" element={
        <ProtectedRoute isAuthenticated={isAuthenticated}>
          <LoginPage />
        </ProtectedRoute>
      } />
      <Route path="/" element={<HomePage />} />
    </Routes>
  );
}

验证逻辑

  • 当已登录用户从其他页面(如首页)导航到/login时,location.key不为default,会执行navigate(-1)返回上一页
  • 当已登录用户新开标签页直接访问/login时,location.key为default,会跳转到首页

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 00:36:29