React Router DOM报错TypeError: Cannot read 'push' of undefined 如何解决?
解决React类组件中history.push报错“'push' is undefined”的问题
错误原因
- 错误使用Hook:你导入的
useHistory是React Router的Hook,只能在函数组件或自定义Hook中使用,类组件里无法生效,而且你也没实际调用它,这行导入完全多余。 - 未获取到history prop:类组件只有在被
<Route>直接渲染,或者被withRouter高阶组件包裹时,才能拿到history对象。你的组件没满足这两个条件,所以this.props.history是undefined,调用push自然报错。
解决方案
方案一:用withRouter包裹类组件(保留类组件结构)
- 移除无用的
useHistory导入,改为导入withRouter - 导出组件时用
withRouter包裹,让组件能获取到historyprop
修改后的完整代码:
import { withRouter } from 'react-router-dom' import { Component } from 'react' import axios from 'axios' import { Row, Col, Button } from 'react-bootstrap' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faShoppingCart } from '@fortawesome/free-solid-svg-icons' export default withRouter(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> ) } })
方案二:改为函数组件使用useHistory(推荐)
React官方更推荐函数组件+Hook的写法,直接用useHistory获取history对象:
import { useHistory } from 'react-router-dom' import { Row, Col, Button } from 'react-bootstrap' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faShoppingCart } from '@fortawesome/free-solid-svg-icons' import axios from 'axios' export default function TotalPrice(props) { const history = useHistory() const checkout = (sum) => { const order = { total_bayar: sum, menus: props.carts } axios.post(API_URL + "orders", order).then((res) => { history.push('/order-success') }) } const sum = props.carts.reduce((result, item) => 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={() => checkout(sum)} > <FontAwesomeIcon icon={faShoppingCart} /> Checkout </Button> </Col> </Row> ) }
额外注意
确保你的整个应用被<BrowserRouter>(或其他Router组件,比如HashRouter)包裹,例如在根组件App.js中:
import { BrowserRouter } from 'react-router-dom' function App() { return ( <BrowserRouter> {/* 你的路由和组件都要放在这里面 */} <TotalPrice /> </BrowserRouter> ) }
内容的提问来源于stack exchange,提问作者leo
相关产品推荐
相关产品推荐

