This.props.history.push works in some components and not in others.

I am trying to programmatically change pages using browserHistory.push . In one of my components, but not in the component that I embedded inside of this.

Does anyone know why my project throws an error below only for the child component, but not for the parent component?

Unable to read the "push" property from undefined

Parent component

 import React, {Component} from 'react'; import { browserHistory } from 'react-router'; import ChildView from './ChildView'; class ParentView extends Component { constructor(props) { super(props); this.addEvent = this.addEvent.bind(this); } changePage() { this.props.history.push("/someNewPage"); } render() { return ( <div> <div> <button onClick={this.changePage}>Go to a New Page!</button> </div> <ChildView /> // this is the child component where this.props.history.push doesn't work </div> ); } } function mapStateToProps(state) { return { user: state.user }; } function matchDispatchToProps(dispatch) { return bindActionCreators({ setName: setName }, dispatch) } export default connect(mapStateToProps, matchDispatchToProps)(ParentView); 

Child component

  import React, {Component} from 'react'; import { browserHistory } from 'react-router'; class ChildView extends Component { constructor(props) { super(props); this.addEvent = this.addEvent.bind(this); } changePage() { this.props.history.push("/someNewPage"); } render() { return ( <div> <div> <button onClick={this.changePage}>Go to a New Page!</button> </div> </div> ); } } function mapStateToProps(state) { return { user: state.user }; } function matchDispatchToProps(dispatch) { return bindActionCreators({ setName: setName }, dispatch) } export default connect(mapStateToProps, matchDispatchToProps)(ChildView); 

router

 // Libraries import React from 'react'; import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; import { browserHistory } from 'react-router'; // Components import NotFound from './components/NotFound'; import ParentView from './components/ParentView'; import ChildView from './components/ChildView'; import SomeNewPage from './components/SomeNewPage'; // Redux import { Provider } from 'react-redux'; import {createStore} from 'redux'; import allReducers from './reducers'; const store = createStore( allReducers, window.devToolsExtension && window.devToolsExtension() ); const routes = ( <Router history={browserHistory}> <div> <Provider store={store}> <Switch> <Route path="/" exact component={Home} /> <Route path="/parentView" component={ParentView} /> <Route path="/someNewPage" component={SomeNewPage} /> <Route path="/childView" component={ChildView} /> <Route component={NotFound} /> </Switch> </Provider> </div> </Router> ); export default routes; 

As you can see, the components are almost the same, except that the child is inside the parent.

Note. I tried these approaches, but they do not solve the problem for me:

  • Uncaught TypeError: Unable to read the "push" property from undefined with import loaded correctly
  • BrowserHistory.push response giving Uncaught TypeError: Cannot read the 'push' property from undefined
  • redirect to the page programmatically in interaction-router mode 2
+7
javascript reactjs react-router router
source share
2 answers

You answered your question in your question.

As you can see, the components are almost the same, except that the child is inside the parent.

The fact that another component is nested is your problem. React router only injects the routing details into the component to which it was directed, but not to the components embedded in.

See the accepted answer to this question. The basic idea is that now you need to find a way to enter the routing details for the child component. You can do this by wrapping the child in a HOC withRouter .

 export default withRouter(connect(mapStateToProps, matchDispatchToProps)(ChildView)); 

Hope this helps.

+12
source share

Using withRouter is fine, an alternative is to pass the story as a support from parent to child (without using withRouter), for example:

Parent

 <SignupForm history={this.props.history}/> 

Child

 this.props.history.push('/dashboard'); 
0
source share

All Articles