Programmatic navigation from action creator using React Router V4

React Router 4 has made tremendous updates not only in terms of features and syntax but also in terms of coding design patterns and philosophies.

I created this post because I know a number of developers who give on React Router v4 when they try to accomplish things, such as programmatic navigation, which seemed much easier in v3. I will not go into the merits of the decisions by the react router core developers, however this post will attempt to explain one of the best ways to achieve programmatic navigation from an action creator.

This use case is quite common, especially in the context of signing in users - typically we want our React app to redirect the users to a protected route once they have successfully logged in. In V3 this was very simple through the use of the BrowserHistory method to push the new route. This is not supported anymore in V4, and developers are encouraged to use the history object inherited (via props) by the Router component.

So the next big question is - "How can I use the history object from inside an action creator?"Let's say we have an action creator that uses an async request to an API server to login the user. This action creator has no access to this history prop (since it is not a Router component).

Therefore, for an action creator to manipulate the navigation, we have to use some callback logic. I know, I know - you're already shivering by just mentioning callback, but trust me it is quite succinct and intuitive.

The idea is to hook the helper function from, say, an html form's submit button (we will call it conveniently handleFormSubmit()) and call the action creator with a callback as a second argument as follows:

This means that once the action is fired and we get a response back from our API server, React will then push the new route (/feature in our case) to the browser. For this to work we must make sure we have two things in place:

  1. The Signin component is being rendered by the Router (otherwise we cannot access the this.props.history), and
  2. The action creator (this.props.signinUser in this case), accepts a callback as a second argument and executes it when the http request is successful.
A typical action creator will look like this:

No comments: