4

I am developing a web application using React JS. Now, I am trying to programmatically redirect to another route. I can redirect like this.

this.props.history.push('/event/${this.props.id}/edit');

But when I use that in the child component it is not working. This is my scenario. I have a parent component called, EventListComponent. Inside that component, I render another child component called EventWidgetComponent. I am redirecting in the child component. But this.props.history is always undefined when I use it in the child component. How can I fix it?

Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
Wai Yan Hein
  • 13,651
  • 35
  • 180
  • 372

3 Answers3

11

This is happening because your child component doesn't have the access to history. Child component is receiving the props from parent component not from Router, that's why.

These are the possible ways to solve the issue:

1- Either pass a method from parent to child and do the redirecting part inside parent component. Call that method from child component for redirecting.

2- Use withRouter hoc and render the child component inside that, it will provide access of history to child component.

Like this:

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

// Child component here

class Child extends React.Component {
   // code
}

export default withRouter(Child)

Check this answer: Programmatically navigating in React-Router v4

3- Pass the reference of history to child in props:

<Child history={this.props.history} />
Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
  • Thank you so much. Adequate answer. Cheers. BTW. It is not coming home. – Wai Yan Hein Jul 11 '18 at 21:37
  • But second option throw this error. Objects are not valid as a React child (found: object with keys {pathname, search, hash, state}). If you meant to render a collection of children, use an array instead. – Wai Yan Hein Jul 11 '18 at 21:43
  • that error means somewhere in the code you are rendering the `history object`, that contains `pathname, search, state etc`, something like this: `
    {this.props.history}
    `. Objects are not a valid element, render the specific value :)
    – Mayank Shukla Jul 12 '18 at 05:05
3

You can pass the history prop down from the component you are giving to a Route to the child component if you want to use it there.

Example

class App extends React.Component {
  render() {
    return (
      <div>
        {/* ... */}
        <Route exact path="/" component={Parent} />
        {/* ... */}
      </div>
    );
  }
}

class Parent extends React.Component {
  render() {
    return (
      <div>
        <Child history={this.props.history} />
      </div>
    );
  }
}
Tholle
  • 108,070
  • 19
  • 198
  • 189
0

you can pass a prop to the EventWidgetComponent passed from the parent EventListComponent like onHistoryPush:

<EventWidgetComponent onHistoryPush={() => this.props.history.push('/event/${this.props.id}/edit')}