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

无法在Login.js中获取state:{from:props.location}值的技术问询

解决React Router中PrivateRoute重定向后Login组件无法获取state的问题

看起来你遇到的核心问题是重定向时携带的state没有正确传递到Login组件,导致无法获取来源路径from,最终登录成功后无法跳转到用户原本想要访问的页面。我来帮你一步步排查并解决这个问题:

首先,排查最可能的错误:PrivateRoute的重定向路径是否正确

你的PrivateRoute代码里,重定向的目标路径是pathname: '/',但你提到要跳转到登录页——如果你的登录页路由是/login而不是根路径/,那这里就写错了!state只会传递给直接重定向的目标页面,如果先跳转到根路径,再从根路径跳转到登录页,state就会丢失。

先修正PrivateRoute的重定向目标:

const PrivateRoute = ({ ...rest }) => {
  return (
    <Route {...rest} render={(props) => {
      return props.isAuthPass === true ? (
        props.children
      ) : (
        // 把pathname改成你的登录页实际路由,比如'/login'
        <Redirect to={{ 
          pathname: '/login', 
          state: { from: props.location } 
        }} />
      );
    }} />
  );
};

确保Login组件被Route直接渲染

只有被React Router的<Route>组件直接渲染的组件,才能通过props或useLocation拿到正确的location对象。你的路由配置应该类似这样(以React Router v5为例):

import { Switch, Route } from 'react-router-dom';
import Login from './Login';
import Dashboard from './Dashboard';
import PrivateRoute from './PrivateRoute';

function App() {
  const isAuthenticated = false; // 替换成你的认证状态判断逻辑
  return (
    <Switch>
      {/* 登录页必须用Route直接渲染 */}
      <Route path="/login" component={Login} />
      {/* 受保护的路由用PrivateRoute包裹 */}
      <PrivateRoute path="/dashboard" isAuthPass={isAuthenticated}>
        <Dashboard />
      </PrivateRoute>
      {/* 默认路由 */}
      <Route path="/" component={Home} />
    </Switch>
  );
}

在Login组件中正确获取state

根据你的组件类型(函数/类组件),选择对应的方式获取state:

函数组件(推荐用useLocation钩子)

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

const Login = () => {
  const location = useLocation();
  const [redirectToReferrer, setRedirectToReferrer] = useState(false);

  // 从state中取来源路径,默认回到首页
  const from = location.state?.from || { pathname: "/" };

  const handleLogin = () => {
    // 这里写你的登录逻辑,比如调用登录接口
    // 登录成功后触发跳转
    setRedirectToReferrer(true);
  };

  if (redirectToReferrer) {
    return <Redirect to={from} />;
  }

  return (
    <div>
      <h1>登录页</h1>
      <input type="text" placeholder="用户名" />
      <input type="password" placeholder="密码" />
      <button onClick={handleLogin}>登录</button>
    </div>
  );
};

export default Login;

类组件(通过props获取location)

import { Redirect } from 'react-router-dom';
import React, { Component } from 'react';

class Login extends Component {
  state = {
    redirectToReferrer: false
  };

  handleLogin = () => {
    // 登录逻辑完成后更新状态
    this.setState({ redirectToReferrer: true });
  };

  render() {
    const { redirectToReferrer } = this.state;
    const { location } = this.props;
    const from = location.state?.from || { pathname: "/" };

    if (redirectToReferrer) {
      return <Redirect to={from} />;
    }

    return (
      <div>
        <h1>登录页</h1>
        <input type="text" placeholder="用户名" />
        <input type="password" placeholder="密码" />
        <button onClick={this.handleLogin}>登录</button>
      </div>
    );
  }
}

export default Login;

如果是React Router v6的情况(API有变化)

如果你的项目用的是React Router v6,PrivateRoute的写法需要调整,因为v6移除了render属性和Redirect组件,改用Navigate和Outlet:

先写v6版本的PrivateRoute

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

const PrivateRoute = ({ isAuthPass }) => {
  // 用window.location.pathname获取用户原本要访问的路径
  return isAuthPass ? <Outlet /> : <Navigate to="/login" replace state={{ from: window.location.pathname }} />;
};

路由配置

import { Routes, Route } from 'react-router-dom';
import Login from './Login';
import Dashboard from './Dashboard';
import PrivateRoute from './PrivateRoute';

function App() {
  const isAuthenticated = false;
  return (
    <Routes>
      <Route path="/login" element={<Login />} />
      {/* 受保护路由的写法 */}
      <Route element={<PrivateRoute isAuthPass={isAuthenticated} />}>
        <Route path="/dashboard" element={<Dashboard />} />
      </Route>
      <Route path="/" element={<Home />} />
    </Routes>
  );
}

v6版本的Login组件

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

const Login = () => {
  const location = useLocation();
  const navigate = useNavigate();
  const from = location.state?.from || '/';

  const handleLogin = () => {
    // 登录逻辑完成后跳转
    navigate(from);
  };

  return (
    <div>
      <h1>登录页</h1>
      <input type="text" placeholder="用户名" />
      <input type="password" placeholder="密码" />
      <button onClick={handleLogin}>登录</button>
    </div>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:23:14