web-dev-qa-db-fra.com

Uncaught TypeError: impossible de lire la propriété 'Push' de undefined (React-Router-Dom)

J'ai un Tableau de bord avec des diapositives en rotation, dont chacune a un onglet correspondant dans Bâtiments . Dashboard.js et Bldgs.js sont des enfants de mon App.js.

Lorsqu'un utilisateur clique sur une diapositive A dans Dashboard.js, Dashboard doit indiquer App.js pour que App puisse indiquer à Bldgs.js de faire afficher l'onglet A lors de son routage vers Bldgs.

Je crois que je passe la valeur d'index correcte de Dashboard jusqu'à App et jusqu'à Bldgs. Cependant, une erreur est générée dans mon fichier App.js en indiquant:

Uncaught TypeError: Cannot read property 'Push' of undefined

Mon code fonctionnait bien avant que je commence à transmettre ma fonction handleClick() à mon composant 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')
);

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;
19
Mike

Pour utiliser history dans le composant App, utilisez-le avec withRouter. Vous devez utiliser withRouter uniquement lorsque votre composant ne reçoit pas le Router props,

Cela peut arriver dans les cas où votre composant est un enfant imbriqué d'un composant rendu par le routeur} ou vous ne lui avez pas transmis les accessoires du routeur ou lorsque le composant est pas lié au routeur} et est rendu en tant que composant distinct des itinéraires.

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

Documentation sur le routeur

31
Shubham Khatri

Vous essayez de pousser avec sans donner la tâche à une bibliothèque valide. sur App.js 

Donc: Sur App.js

Vous utilisez BrowserRouter, qui gère l'historique des pages par défaut. Avec cette fonction react-router-dom, vous vous basez sur BrowserRouter pour le faire à votre place. 

Utilisez Router au lieu de BrowserRouter pour prendre le contrôle de votre historique, utilisez-le pour contrôler le comportement. 

  1. Utilisez l'historique npm "fil add [email protected]"/"npm i [email protected]"
  2. import Route à partir de 'react-router-dom'; // n'utilise pas BrowserRouter
  3. importer createBrowserHistory de 'createBrowserHistory'; 

N'oubliez pas de l'exporter !! Export const historique = createBrowserHistory ();

4.importez l’historique dans Dashboard.js Histoire 5.import à Bldgs.js

espérons que cela aide !!! @ brunomiyamotto 

0

Voir mon fichier App.js ci-dessous. J'ai fini par transmettre {...this.props} au composant NavBar que j'avais créé ... Le composant NavBar ne fait pas partie de mes routes 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);

Dans ma barre de navigation. Le bouton que j'ai utilisé avait le code suivant. Je devais .bind (this) pour voir l'historique et pouvoir utiliser this.props.history.Push("/")

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