未捕获的TypeError:无法读取未定义的属性'push'(React-Router-Dom)

Mik*_*ike 29 javascript reactjs react-router react-router-dom

我有一个带旋转幻灯片的仪表板,每个幻灯片在Bldgs中都有一个相应的标签.两者Dashboard.jsBldgs.js有孩子我App.js.

当用户点击特定幻灯片ADashboard.js,Dashboard需要告知App.js以便在路由到时App可以告诉显示Bldgs.js标签.ABldgs

相信,我传递正确的索引值从Dashboard最高App和向下Bldgs.但是,我的App.js文件中引发了一个错误:

Uncaught TypeError: Cannot read property 'push' of undefined

在我开始将handleClick()函数传递给Dashboard组件之前,我的代码工作正常.

Index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
import injectTapEventPlugin from 'react-tap-event-plugin';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import { BrowserRouter as Router } from 'react-router-dom';
import { hashHistory } from 'react-router';

// Needed for onTouchTap
// http://stackoverflow.com/a/34015469/988941
injectTapEventPlugin();

ReactDOM.render(
  <MuiThemeProvider>
    <Router history={hashHistory}>
      <App />
    </Router>
  </MuiThemeProvider>,
  document.getElementById('root')
);
Run Code Online (Sandbox Code Playgroud)

App.js

import React from 'react';
import { Route } from 'react-router-dom';
import Dashboard from './Dashboard';
import Bldgs from './Bldgs';

var selectedTab;

class App extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
    selectedTab = 0;
  }

  handleClick(value) {
    selectedTab = value;
    // console.log(selectedTab);
    this.props.history.push('/Bldgs');
    // console.log(this.props);
  }

  render() {
    var _this = this;

    return (
      <div>
        <Route exact path="/" render={(props) => <Dashboard {...props} handleClick={_this.handleClick} />} />
        <Route path="/Bldgs" component={Bldgs} curTab={selectedTab} />
      </div>
    );
  }
}

export default App;
Run Code Online (Sandbox Code Playgroud)

Dashboard.js

import React, { Component } from 'react';
import './Dashboard.css';
import { AutoRotatingCarousel, Slide } from 'material-auto-rotating-carousel';
...

var curIndex;

class Dashboard extends Component {
  constructor(props) {
    super(props);
    this.handleEnter = this.handleEnter.bind(this);
    this.handleChange = this.handleChange.bind(this);
    curIndex = 0;
  }

  handleEnter(e) {
    // console.log(curIndex);
    this.props.handleClick(curIndex);
  }

  handleChange(value) {
    // console.log(value);
    curIndex = value;
  }

...
}

export default Dashboard;
Run Code Online (Sandbox Code Playgroud)

Bldgs.js

...
var curTab;

class Bldgs extends Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.goHome = this.goHome.bind(this);
    curTab = 0;
  }

  handleChange(value) {
    this.setState({'selectedTab': value});
    console.log(this.state);
  }

  goHome(e) {
    this.props.history.push('/');
  }

...
}

export default Bldgs;
Run Code Online (Sandbox Code Playgroud)

Shu*_*tri 51

为了使用historyApp组件中使用它withRouter.withRouter只有在组件没有收到时才需要使用Router props,

如果您的组件是由路由器呈现的组件的嵌套子级,或者您没有将Router支持传递给它,或者组件根本没有链接到路由器并且从组件呈现为单独的组件,则可能会发生这种情况.路线.

import React from 'react';
import { Route , withRouter} from 'react-router-dom';
import Dashboard from './Dashboard';
import Bldgs from './Bldgs';

var selectedTab;

class App extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
    selectedTab = 0;
  }

  handleClick(value) {
    selectedTab = value;
    // console.log(selectedTab);
    this.props.history.push('/Bldgs');
    // console.log(this.props);
  }

  render() {
    var _this = this;

    return (
      <div>
        <Route exact path="/" render={(props) => <Dashboard {...props} handleClick={_this.handleClick} />} />
        <Route path="/Bldgs" component={Bldgs} curTab={selectedTab} />
      </div>
    );
  }
}

export default withRouter(App);
Run Code Online (Sandbox Code Playgroud)

有关withRouter的文档


Aaq*_*uib 16

使用函数式组件时,我们可以使用 useHistory() to history to push 方法

import { useHistory } from "react-router-dom";
Run Code Online (Sandbox Code Playgroud)

然后在函数中我们必须分配 useHistory()

  let history = useHistory();
Run Code Online (Sandbox Code Playgroud)

现在我们可以使用 history.push 重新定位到所需的页面

history.push('/asdfg')
Run Code Online (Sandbox Code Playgroud)

  • 我知道,但我也想为现在也使用钩子的人提供解决方案,这个答案是三年前问的,现在人们已经更多地转向功能组件,并且问题不只指定关于类组件,所以如果现在人们找到这个问题,希望他们也能找到我的钩子解决方案 (7认同)
  • 我就是这么做的,这就是我来这里的原因...... (2认同)
  • 它对我解决问题有很大帮助。谢谢。 (2认同)

cry*_*KTM 13

对于React-router V4, 将功能更改为

onClick={this.fun.bind(this)}

fun() {
  this.props.history.push("/Home");
}
Run Code Online (Sandbox Code Playgroud)

import { withRouter } from 'react-router-dom';
Run Code Online (Sandbox Code Playgroud)

稍后将其导出为:

export default withRouter (comp_name);
Run Code Online (Sandbox Code Playgroud)

  • 为什么导入`browserHistory`? (3认同)