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

react-router-dom v6类组件如何实现登录后页面重定向

问题根因

react-router-dom v6 已移除v5版本默认给类组件注入的history prop,同时废弃history.push()跳转写法,统一用navigate方法处理路由导航,直接访问this.props.history会得到undefined,触发Cannot read properties of undefined (reading 'push')报错。

v6版本类组件实现登录后跳转的可行方案

不需要降级到v5版本,以下两种都是官方兼容的稳定写法:

  • 方案1:自定义withRouter高阶组件注入navigate(推荐,改动最小)

v6没有内置类组件用的withRouter方法,自己封装一个高阶组件,把hooks提供的navigate注入到类组件props中即可,不需要大幅修改原有业务逻辑。
首先封装高阶组件:

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

export const withRouter = (WrappedComponent) => {
  return function RouterWrapper(props) {
    const navigate = useNavigate();
    // 可按需注入useLocation、useParams等其他路由能力
    return <WrappedComponent {...props} navigate={navigate} />;
  };
};

修改Auth组件代码:

  1. 引入封装好的withRouter,导出组件时用它包裹
  2. 把原有报错的this.props.history.push('/dashboard')替换为this.props.navigate('/dashboard')
    核心修改片段:
// 引入withRouter,路径替换为你实际存放高阶组件的文件路径
import { withRouter } from './utils/withRouter';

class Auth extends Component { 
    constructor(props) {
        super(props);
        this.state = {
            tab: 'signin'
        }
    }
    SignIn = (email, password) => {
        axios.post('/api/users/login', {email, password}).then(res => {
            if(res.data.success) {
                store.dispatch({
                    type: 'login',
                    _id: res.data.user._id,
                    user: res.data.user,
                    token: res.data.token
                });
                // 替换原有history.push逻辑
                this.props.navigate('/dashboard');               
            }
        }).catch(er => {
            if (er.response) {
                console.log(er.response.data);
                console.log(er.response.status);
                console.log(er.response.headers);
              } else if (er.request) {
                console.log(er.request);
              } else {
                console.log('er', er.message);
              }
              console.log(er.config);
        })     
    }
    // 其余组件逻辑(render、其他方法)保持不变
}

// 导出时用withRouter包裹
export default withRouter(Auth);

如果需要实现v5中history.replace的效果(跳转后不保留当前页在历史栈),调用this.props.navigate('/dashboard', { replace: true })即可。

  • 方案2:通过状态控制渲染Navigate组件(无需封装额外工具函数)

利用v6内置的<Navigate>组件,通过组件状态控制跳转时机,不需要写高阶组件或者hooks封装:

  1. 在组件state中新增跳转标记字段
  2. 登录成功后更新state,设置跳转目标路径
  3. render方法中优先判断跳转标记,满足条件时返回Navigate组件完成跳转
    核心修改片段:
// 引入Navigate组件
import { Navigate } from 'react-router-dom';

class Auth extends Component { 
    constructor(props) {
        super(props);
        this.state = {
            tab: 'signin',
            redirectPath: '' // 新增跳转路径状态
        }
    }
    SignIn = (email, password) => {
        axios.post('/api/users/login', {email, password}).then(res => {
            if(res.data.success) {
                store.dispatch({
                    type: 'login',
                    _id: res.data.user._id,
                    user: res.data.user,
                    token: res.data.token
                });
                // 更新状态触发重渲染,执行跳转
                this.setState({
                  redirectPath: '/dashboard'
                });               
            }
        }).catch(er => {
            // 原有错误处理逻辑保持不变
            if (er.response) {
                console.log(er.response.data);
                console.log(er.response.status);
                console.log(er.response.headers);
              } else if (er.request) {
                console.log(er.request);
              } else {
                console.log('er', er.message);
              }
              console.log(er.config);
        })     
    }

    render() {
      // 优先判断是否需要跳转
      if (this.state.redirectPath) {
        // 需要替换历史栈就加replace属性
        return <Navigate to={this.state.redirectPath} replace />
      }
      // 原有登录页渲染逻辑保持不变
      return (
        <div>
          {/* 原有的登录/注册表单内容 */}
        </div>
      )
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 21:57:23