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

React类组件使用history报错cannot read property push of undefined如何解决

报错原因

你遇到的can not read property push of undefined报错,本质是当前组件不是路由直接渲染的组件,props中没有被自动注入history对象。只有通过<Route component={CentralBar} />方式直接挂载的组件,才会默认拿到路由相关的props,非路由嵌套组件默认无法直接获取。

类组件路由跳转的几种可行方案

方案1:使用withRouter高阶组件(适用于react-router-dom v5及更早版本)

withRouter是官方提供的高阶组件,可以把路由相关的props注入到任意组件中,修改代码如下:

import React, { Component } from 'react';
// 引入withRouter
import { withRouter } from 'react-router-dom';

class CentralBar extends Component {
    constructor(props){
        super(props)
        this.state = {}
        this.someText = this.someText.bind(this);
    }

    someText(){
        this.props.history.push(`/login/`);
    }

    render() {
        return (
            <div className="crentralPanel">
                {/* 注意React里要把class改成className */}
                <button type="button" className="btn btn-light" onClick={this.someText}>Click on Text</button>
            </div>
        );
    }
}

// 导出时用withRouter包裹组件
export default withRouter(CentralBar);

方案2:自定义高阶组件适配react-router-dom v6

v6版本移除了withRouter,同时把history.push换成了navigate方法,你可以自行封装高阶组件适配类组件:

  1. 先封装通用的withRouter高阶组件:
// src/utils/withRouter.js
import { useNavigate, useLocation, useParams } from 'react-router-dom';

export default function withRouter(Component) {
  function ComponentWithRouterProp(props) {
    const location = useLocation();
    const navigate = useNavigate();
    const params = useParams();
    return <Component {...props} router={{ location, navigate, params }} />;
  }
  return ComponentWithRouterProp;
}
  1. 修改你的组件代码:
import React, { Component } from 'react';
import withRouter from './utils/withRouter';

class CentralBar extends Component {
    constructor(props){
        super(props)
        this.state = {}
        this.someText = this.someText.bind(this);
    }

    someText(){
        // v6用navigate方法跳转
        this.props.router.navigate(`/login/`);
    }

    render() {
        return (
            <div className="crentralPanel">
                <button type="button" className="btn btn-light" onClick={this.someText}>Click on Text</button>
            </div>
        );
    }
}

export default withRouter(CentralBar);

方案3:声明式跳转(无额外业务逻辑时优先使用)

如果点击按钮不需要执行额外的业务逻辑,直接跳转的话,用官方提供的<Link>组件更符合React声明式写法规范:

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

class CentralBar extends Component {
    render() {
        return (
            <div className="crentralPanel">
                <Link to="/login/">
                    <button type="button" className="btn btn-light">Click on Text</button>
                </Link>
            </div>
        );
    }
}

export default CentralBar;

方案4:全局history对象(通用所有版本)

你也可以创建全局统一的history对象,任意组件都可以直接导入使用,不需要依赖props注入:

  1. 创建history实例:
// src/history.js
// v5版本直接用history库的createBrowserHistory,v6可以用react-router-dom导出的createBrowserHistory
import { createBrowserHistory } from 'history';
export default createBrowserHistory();
  1. 入口文件替换Router配置:
import { Router } from 'react-router-dom';
import history from './history';
import App from './App';

ReactDOM.render(
  <Router history={history}>
    <App />
  </Router>,
  document.getElementById('root')
);
  1. 组件中直接导入使用:
import React, { Component } from 'react';
import history from './history';

class CentralBar extends Component {
    someText(){
        history.push('/login/');
    }

    render() {
        return (
            <div className="crentralPanel">
                <button type="button" className="btn btn-light" onClick={this.someText.bind(this)}>Click on Text</button>
            </div>
        );
    }
}

export default CentralBar;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 09:36:09