0

I just learned react, when button is clicked I want to navigate, but it doesn't and gives an error that 'push' is undefined, how to solve it?

import { Route, useHistory as history } from 'react-router-dom'

export default class TotalPrice extends Component {
  checkout = (sum) => {
    const order = {
      total_bayar: sum,
      menus: this.props.carts
    }

    axios.post(API_URL + "orders", order).then((res) => {
      this.props.history.push('/order-success')
    })
  } 
  render() {
    const sum = this.props.carts.reduce(function (result, item) {
      return result + item.total_price;
    }, 0);

    return (
      <Row className='fixed-bottom'>
        <Col md={{span: 3, offset: 9}} className='py-4 px-4 total'>
          <h4>
            Total : <strong className='total-number'>Rp. {priceSplitter(sum)}</strong>
          </h4>
          <Button
            variant="primary"
            className="button-checkout"
            onClick={() => this.checkout(sum)}
          >
            <FontAwesomeIcon icon={faShoppingCart} />
            Checkout
          </Button>
        </Col>
      </Row>
    )
  }
}

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
leo
  • 139
  • 9
  • 1
    `history` isn't in your props. See https://v5.reactrouter.com/web/api/Hooks/usehistory. You also cannot use hooks in class components – Phil Aug 09 '22 at 02:06

1 Answers1

1

The error is saying that this.props.history is undefined. Since it appears that you are using react-router-dom@5 you can import and use the withRouter Higher Order Component and decorate this TotalPrice component to inject the route props.

import { Route, withRouter } from 'react-router-dom'

class TotalPrice extends Component {
  checkout = (sum) => {
    const order = {
      total_bayar: sum,
      menus: this.props.carts
    };

    axios.post(API_URL + "orders", order)
      .then((res) => {
        this.props.history.push('/order-success');
      });
  }

  render() {
    const sum = this.props.carts.reduce(function (result, item) {
      return result + item.total_price;
    }, 0);

    return (
      <Row className='fixed-bottom'>
        <Col md={{span: 3, offset: 9}} className='py-4 px-4 total'>
          <h4>
            Total : <strong className='total-number'>Rp. {priceSplitter(sum)}</strong>
          </h4>
          <Button
            variant="primary"
            className="button-checkout"
            onClick={() => this.checkout(sum)}
          >
            <FontAwesomeIcon icon={faShoppingCart} />
            Checkout
          </Button>
        </Col>
      </Row>
    );
  }
}

export default withRouter(TotalPrice);

If you are using react-router-dom@6 then you will have to roll your own custom withRouter HOC if you want to continue using React class-based components since RRDv6 doesn't export any withRouter HOC like v5 did, and there are only React hooks available to use in components. You can follow my answer here for brief explanation and code example.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Attempted import error: 'withRouter' is not exported from 'react-router-dom'. – leo Aug 09 '22 at 04:03
  • @leo I see. Does my answer [here](/a/69902006/8690857) resolve your question/issue? – Drew Reese Aug 09 '22 at 04:08
  • I've created a new new file for withrouter, but still can't. here is error message Attempted import error: 'withRouter' is not exported from './withRouter'. – leo Aug 09 '22 at 04:24
  • @leo How did you export your `withRouter` function? Did you import it correctly? I.E. is it a default or named export? – Drew Reese Aug 09 '22 at 04:29