10

If I'm always redirecting to in-app routes, what's the difference between the Redirect component in react-router-dom (v4), and this.props.history.push()?

E.g. let's say I want to add a user-given title to the URL and redirect from /foo/123 to /foo/123/some-title (both rendered with same Route/component).

I see in some uses of Redirect passing in state. Where does this end up?

Is it an anti-pattern to specify where you want to redirect to in the state? Why doesn't example code look like this:

save() {
  this.setState({ redir: '/new-path'; });
}
...
render () {
  if (this.state.redir) {
    return <Redirect to={this.state.redir} />;
  }
  ...
}
Steve Clay
  • 8,090
  • 2
  • 38
  • 46

1 Answers1

6

I am someone who is sternly against rendering redirects as it is kind of counterintuitive that you have to render a component in order to change the page however it does provide some clear benefits

so the issue with this.props.history.push() is mostly when you are dealing with child components that are triggering redirects

Component A # the one Rendered by the Route
  Component B
    Component C # the one triggering the redirect

in the example above, unless you are diligent with passing down the route props from Component A down to Component C, then you wouldn't be able to use history.push() in Component C

Rendering Redirect was supposed to be the answer to that scenario that was provided by the maintainer of react-router but some people just dont like the idea at all(me included).


Functioanally speaking, there doesnt seem to be major differences in functionality between Redirect and history.push as Redirect uses it under the hood. The major reason to use Redirect over history.push is that Redirect is future proofed from possible changes on how history would work or if they decide to handle context differently at a later date.

Maru
  • 540
  • 5
  • 14
  • 2
    by wrapping your component with `withRouter` you can get access to the router props at any level of hierarchy – Shubham Khatri Oct 15 '17 at 17:32
  • @ShubhamKhatri true, as long as the component that used `withRouter` as an HOC uses history solely for push then there shouldn't be an issue. in my case, I one tried accessing `match` from a component that used `withRouter` and I didnt get the results I wanted – Maru Oct 15 '17 at 17:38
  • 1
    So does Redirect use history.push under the hood? I'd like to know the behavioral differences ideally. – Steve Clay Oct 15 '17 at 17:55
  • Docs don't mention state at all. – Steve Clay Oct 15 '17 at 18:03
  • 2
    yes, `Redirect` uses `history.push` under the hood. I dont see any major behavioral difference between the two aside from `Redirect` being future proofed from whatever changes to the `context` or `history` object that may or could happen later on in time – Maru Oct 15 '17 at 18:04
  • @SteveClay my bad about the docs part, I have removed it from my answer. I'm not aware of passing states in a redirect component and it doesnt look like it does anything from the source either https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/Redirect.js – Maru Oct 15 '17 at 18:11
  • I should've just read the source! Didn't think it'd be so simple. Thanks for updating your answer. – Steve Clay Oct 15 '17 at 20:48
  • @SteveClay I would appreciate it if you accepted the answer as well as an update. thanks – Maru Oct 16 '17 at 09:37