Uncaught TypeError: Невозможно прочитать свойство 'push' из неопределенного (React-Router-Dom)

У меня есть панель инструментов с вращающимися слайдами, каждая из которых имеет соответствующую вкладку в Bldgs. И то и другое Dashboard.js а также Bldgs.js дети для меня App.js,

Когда пользователь нажимает на определенный слайд A в Dashboard.js, Dashboard нужно сказать App.js чтобы App могу сказать Bldgs.js иметь вкладку A отображается, когда он направляется в Bldgs,

Я считаю, что я передаю правильное значение индекса из 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://stackru.com/a/34015469/988941
injectTapEventPlugin();

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

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;

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;

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;

7 ответов

Решение

Для того, чтобы использовать history в App компонент использовать его с withRouter, Вы должны использовать withRouter только когда ваш компонент не получает Router props,

Это может происходить в тех случаях, когда ваш компонент является вложенным дочерним элементом компонента, отображаемого маршрутизатором, или вы не передали ему реквизиты маршрутизатора, или когда компонент вообще не связан с маршрутизатором и отображается как отдельный компонент от Маршруты.

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);

Документация по с Роутер

для React-router V4 измените функцию на

OnClick={this.fun.bind(это)}

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

  }

а также

import {browserHistory,withRouter} from "react-router-dom"

export default withRouter (comp_name);

Мы можем использовать useHistory() для истории, чтобы протолкнуть метод

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

а затем в функции мы должны назначить useHistory()

  let history = useHistory();

Теперь мы можем использовать history.push для перехода на нужную страницу.

history.push('/asdfg')

Моя ошибка была неправильным смыслом в сочетании с BrowserRouter, то есть:

неверно:

import { useHistory } from 'react-router'

верный:

import { useHistory } from 'react-router-dom'

Вы пытаетесь выдать задание действительной библиотеке. на App.js

Итак: на App.js

Вы используете BrowserRouter, который по умолчанию обрабатывает историю страниц, с помощью этой функции response-router-dom вы полагаетесь на BrowserRouter, чтобы сделать это для вас.

Используйте Router вместо BrowserRouter, чтобы получить контроль над своей историей, используйте историю, чтобы контролировать поведение.

  1. Использовать историю npm "yarn add history@4.xx" / "npm i history@4.xx"
  2. импортировать маршрут из'act-router-dom'; // не использовать BrowserRouter
  3. импортировать createBrowserHistory из 'createBrowserHistory';

Не забудьте вывезти это!! экспорт const history = createBrowserHistory ();

4. импортировать историю в Dashboard.js 5. импортировать историю в Bldgs.js

надеюсь это поможет!!! @brunomiyamotto

Я решил эту ошибку, обернув компонент внутри BrowserRouter.
Не забывайте об этом, это очень распространенная ошибка.

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

<BrowserRouter>
    <Menu/>
<BrowserRouter>    

Только дети маршрутизатора получают перехватчик истории.

Смотрите мой файл App.js ниже. Я кончил {...this.props} к компоненту NavBar, который я создал. Компонент NavBar не является частью моих маршрутов коммутатора.

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.props.history.push("/")

<Button
   color="inherit"
   onClick={this.handleLogout.bind(this)}>Logout</Button>
Другие вопросы по тегам