未捕获的类型错误:无法读取未定义的属性“推送”(React-Router-Dom)

IT技术 javascript reactjs react-router react-router-dom
2021-02-03 10:14:56

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

当用户单击特定的幻灯片ADashboard.jsDashboard需要告诉,App.js以便App可以告诉在路由到 时显示Bldgs.js选项卡ABldgs

相信我正在将正确的索引值从Dashboardup 传递AppBldgs. 但是,我的App.js文件中抛出了一个错误,指出:

Uncaught TypeError: Cannot read property 'push' of undefined

在我开始将handleClick()函数传递Dashboard组件之前,我的代码运行良好

索引.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')
);

应用程序.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;

仪表板.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;

建筑.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;
6个回答

为了historyApp组件中使用,将它与withRouter. 你需要使用的withRouter,只有当你的组件不接受Router props

如果您的组件是由 Router 渲染的组件的嵌套子组件,或者您没有将 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);

withRouter 的文档

添加了 withRouter 文档,其中描述了这一点。
2021-03-26 10:14:56
这个小小的改变使一切正常,但你能解释一下它在做什么吗?谢谢!
2021-04-02 10:14:56

对于 React-router V4, 将函数更改为

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

fun() {
  this.props.history.push("/Home");
}

import { withRouter } from 'react-router-dom';

稍后将其导出为:

export default withRouter (comp_name);
为什么要导入browserHistory
2021-03-17 10:14:56
不需要使用 bind(this) 你可以使用 onClick={this.fun}
2021-03-21 10:14:56

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

import { useHistory } from "react-router-dom";

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

  let history = useHistory();

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

history.push('/asdfg')
OP 正在使用类组件,因此不可能在其中使用钩子 + 当时,当提出问题时,不可能使用钩子,因为它们不存在。
2021-03-15 10:14:56
我知道,但我也想为现在也使用钩子的人提供解决方案,这个答案是 3 年前提出的,现在人们更多地转向了功能组件,而且这个问题并没有只指定类组件,所以如果现在人们找到这个问题,希望他们也能找到我的钩子解决方案
2021-03-26 10:14:56
它对我解决问题有很大帮助。谢谢。
2021-04-05 10:14:56
我就是这么干的,这就是我来这里的原因……
2021-04-13 10:14:56

您试图在不将任务交给有效库的情况下进行推送。在 App.js 上

所以:在 App.js 上

您正在使用 BrowserRouter,它默认处理页面的历史记录,通过这个 react-router-dom 功能,您依靠 BrowserRouter 来完成此操作。

使用 Router 而不是 BrowserRouter 来控制你的历史,使用历史来控制行为。

  1. 使用 npm history "yarn add history@4.xx" / "npm i history@4.xx"
  2. 从'react-router-dom'导入路由;//不要使用BrowserRouter
  3. 从“createBrowserHistory”导入 createBrowserHistory;

记得导出!!导出 const 历史记录 = createBrowserHistory();

4.将历史导入到 Dashboard.js 5.将历史导入到 Bldgs.js

希望这可以帮助 !!!@brunomiyamotto

请参阅下面的 App.js 文件。我最终传递{...this.props}给我创建的 NavBar 组件。NavBar 组件不是我的 Switch 路由的一部分。

import React, { Component } from 'react';
import { Route, Link, Redirect, Switch, withRouter } from 'react-router-dom'

import Navbar from './Navbar.js';
import Home from './Home/HomeCont';
import Login from './Register/Login';
import Dashboard from './Dashboard/DashboardCont';


import './App.css';

class App extends Component {
  constructor(props){
    super(props);

  }

  render() {
    return (
      <div className="App">
        <header className="App-header">

//SOLUTION!!!
          <Navbar {...this.props}/>


        </header>
        <Switch>
          <React.Fragment>
            <Route exact path="/" render={(props) => <Home {...props}/>}/>

            <Route exact path="/login" render={(props) => <Login {...props}/>}/>


          </React.Fragment>


        </Switch>
      </div>
    );
  }
}

export default withRouter(App);

在我的导航栏中。我使用的按钮有以下代码。我必须 .bind(this) 才能查看历史记录并能够使用this.props.history.push("/")

<Button
   color="inherit"
   onClick={this.handleLogout.bind(this)}>Logout</Button>