React中使用Props结合Axios取数时History.push未定义问题
我一眼就看出问题所在啦——你在使用Route的render方法时,没有把Route自动提供的路由相关props(比如history、location)传递给Posts组件!
问题根源
当你用Route的render属性时,React Router会给这个render函数传入一套路由专属的props,但你现在的写法是直接返回<Posts pathname="/posts" filter="food" />,完全没把这些props传进去,所以Posts组件里自然拿不到this.props.history,调用push的时候就会报错。而你硬编码能正常工作,应该是当时的组件本身就处于路由上下文里,能直接拿到这些props。
解决方案
方案1:在render方法中传递Route的props
最简单的修复方式就是把render函数收到的props展开传递给Posts组件:
<Route path="/food" exact render={(routeProps) => <Posts {...routeProps} pathname="/posts" filter="food" />} />
这里的routeProps包含了history、location、match这些关键对象,通过{...routeProps}把它们传递给Posts后,你就能在组件里正常使用this.props.history.push()了。
方案2:用withRouter高阶组件包裹Posts组件
如果你的Posts组件需要在多个地方使用,不想每次都手动传递路由props,可以用React Router提供的withRouter高阶组件来增强它:
首先导入withRouter:
import { withRouter } from 'react-router-dom';
然后在导出组件的时候用withRouter包裹:
class Posts extends Component { // 你的组件逻辑 handlePostClick = (postId) => { this.props.history.push(`/fullpost/${postId}`); } } export default withRouter(Posts);
这样不管Posts是不是直接被Route渲染,都能从props里拿到history等路由相关对象,跳转功能就能正常工作了。
方案3:如果是函数组件,使用useHistory钩子
如果你的Posts是函数组件,还可以直接用React Router的useHistory钩子:
import { useHistory } from 'react-router-dom'; function Posts(props) { const history = useHistory(); const handlePostClick = (postId) => { history.push(`/fullpost/${postId}`); } // 组件渲染逻辑 }
这种方式更简洁,不需要依赖props传递history。
内容的提问来源于stack exchange,提问作者user2986096

