简体   繁体   中英

React Routing and history.push

I'm working with routing of react. Trying to create a menu and redirect from him but im getting error with the routing and history push. I know this duplicate question but i read here from stack and i'm still with the doubt, i dont know why i'm doing wrong. Sorry for the issues but here is my code:

This is my App.js

import React, { Component } from 'react';
import './css/App.css';
import { BrowserRouter, Route,Link} from 'react-router-dom';
import Prueba from './Prueba';
import { ListGroup, ListGroupItem,Collapse, Container, CardBody, Card, Row, Col} from 'reactstrap';
import Menu from './header/Menu';
import Pais from './UbicacionGeneral/Pais';
import history from './UbicacionGeneral/Pais';

class App extends Component {


  constructor(props) {
    super(props);
    this.toggle = this.toggle.bind(this);
    this.state = { collapse: false };
    this.routeChange = this.routeChange.bind(this);
  }


  routeChange() {

    this.props.history.push('Pais');
  }


  toggle(menu) {

  if (this.state.collapse == menu){

    this.setState({ collapse: false }); 

  }else {

    this.setState({ collapse: menu });

  }

  }


 render() {

    return (


  <BrowserRouter>
   <Menu/>
    <div className="App text-center">
      <Row>
        <Col  md="2">
          <ListGroup className="List-Principal">
            <ListGroupItem className="List-Principal-Item " onClick={() => this.toggle("ubicacion")} > Ubicacion General </ListGroupItem>

             <Collapse isOpen={this.state.collapse == "ubicacion"}> 
              <ListGroup>
                <ListGroupItem  onClick={this.routeChange} > Pais </ListGroupItem>
                <ListGroupItem  > Estado </ListGroupItem>
                <ListGroupItem  > Ciudad </ListGroupItem>
              </ListGroup>
            </Collapse>

          <ListGroupItem  className="List-Principal-Item tex-center" 

onClick={() => this.toggle("almacen")} > Almacen </ListGroupItem>
                <Collapse  isOpen={this.state.collapse == "almacen"}>
                  <ListGroup>
                    <ListGroupItem  > Crear - Modificar  </ListGroupItem>
                    <ListGroupItem  > Verificar Stock   </ListGroupItem>
                    <ListGroupItem  > Movimientos  </ListGroupItem>
                  </ListGroup>
                </Collapse>
            </ListGroup>

          </Col>

          <Col  md="10">   
            <Container>
              <Route path="/Prueba" component={Prueba} />
              <Route path="/Pais" component={Pais} />
            </Container>
          </Col>        
        </Row>
      </div>
     </BrowserRouter>
    );
  }
}

export default App;

and this my Pais.js

    import React, { Component } from 'react';
import { ListGroup, ListGroupItem,Collapse, Container, CardBody, Card, Row, Col} from 'reactstrap';
import { Alert } from 'reactstrap';
import { withRouter } from 'react-router-dom';


class Pais extends Component {

  render() {

      return (
        <div>

        <Alert color="primary">
          This is a primary alert — check it out!
        </Alert>
        <Alert color="secondary">
          This is a secondary alert — check it out!
        </Alert>
        <Alert color="success">
          This is a success alert — check it out!
        </Alert>
        <Alert color="danger">
          This is a danger alert — check it out!
        </Alert>
        <Alert color="warning">
          This is a warning alert — check it out!
        </Alert>
        <Alert color="info">
          This is a info alert — check it out!
        </Alert>
        <Alert color="light">
          This is a light alert — check it out!
        </Alert>
        <Alert color="dark">
          This is a dark alert — check it out!
        </Alert>



    </div>
    );
    }

}


export default withRouter (Pais);

I'm trying to click in Pais menu from my App.js in the ListGroupItem but react show this error:

× TypeError: Cannot read property 'push' of undefined

  22 | routeChange() {
  23 | 
> 24 |   this.props.history.push('Pais');
     | ^  25 | }
  26 | 

I'm really stuck with this, thanks for any help!

Wrapping a component with the withRouter hoc passes the location, history and match props to that component. Props cannot be imported. In your case, you would want to make a new component that uses the withRouter hoc somewhere below browser router and move the route change there. eg

MyComponent.js

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.toggle = this.toggle.bind(this);
    this.state = { collapse: false };
    this.routeChange = this.routeChange.bind(this);
  }

  routeChange() {
    this.props.history.push("Pais");
  }

  toggle(menu) {
    if (this.state.collapse == menu) {
      this.setState({ collapse: false });
    } else {
      this.setState({ collapse: menu });
    }
  }
  render() {
    return (
      <div className="App text-center">
        <Row>
          <Col md="2">
            <ListGroup className="List-Principal">
              <ListGroupItem
                className="List-Principal-Item "
                onClick={() => this.toggle("ubicacion")}
              >
                {" "}
                Ubicacion General{" "}
              </ListGroupItem>

              <Collapse isOpen={this.state.collapse == "ubicacion"}>
                <ListGroup>
                  <ListGroupItem onClick={this.routeChange}>
                    {" "}
                    Pais{" "}
                  </ListGroupItem>
                  <ListGroupItem> Estado </ListGroupItem>
                  <ListGroupItem> Ciudad </ListGroupItem>
                </ListGroup>
              </Collapse>

              <ListGroupItem
                className="List-Principal-Item tex-center"
                onClick={() => this.toggle("almacen")}
              >
                {" "}
                Almacen{" "}
              </ListGroupItem>
              <Collapse isOpen={this.state.collapse == "almacen"}>
                <ListGroup>
                  <ListGroupItem> Crear - Modificar </ListGroupItem>
                  <ListGroupItem> Verificar Stock </ListGroupItem>
                  <ListGroupItem> Movimientos </ListGroupItem>
                </ListGroup>
              </Collapse>
            </ListGroup>
          </Col>

          <Col md="10">
            <Container>
              <Route path="/Prueba" component={Prueba} />
              <Route path="/Pais" component={Pais} />
            </Container>
          </Col>
        </Row>
      </div>
    );
  }
}
export default withRouter(MyComponent);
App.js
class App extends Component {
 <BrowserRouter>
   <Menu/>
   <MyComponent/>
 </BrowserRouter>
}

However, it would be simpler and more declarative to just use a Link inside ListGroupItem


import {Link} from "react-router-dom";
...
 <ListGroupItem  onClick={this.routeChange} > <Link to="Pais">Pais </Link> </ListGroupItem>

this way you wouldn't need to mess with the history nor to use withRouter

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM