On the changes in React Router v2

It’s better late than never, so we wanted to take this opportunity to walk through some of the API changes we made between React Router v1 and React Router v2. None of us like API churn, but we wanted to talk about why we made some of the deprecating API changes that we did.

Location descriptors

The API for links and location updates has changed fairly dramatically in React Router v2, thanks to changes in History v2. Instead of writing:

We now have you write:

This does require changes throughout your code whenever you were previously using pushState, and whenever you were using <Link>s with query or state, but in addition to saving typing, it allows for two very cool new patterns.

Merging old and new state

Suppose you wanted to only change the current location query. This was previously quite finicky; you had to remember to assign arguments to the correct slots. With the experimental object spread syntax, this is now a lot easier:

Custom location descriptors (named routes!)

One of the long-standing requests from React Router after the v1 release was for the reintroduction of named routes. That’s right, you can do named routes again. With this concept of location descriptors, this feature is back and better than ever, in that its behavior can be fully specified in user space.

The history enhancer API allows you to configure the behavior of any of those location descriptors. Want named routes? Take a look at use-named-routes and how it’s implemented. All you need to do is to enhance your history with that location descriptor, and now you can push and replace with route names and params, and use those anywhere where you can use paths.

Take a look, and if you need more flexibility, it’s easy to add!

context.history → context.router

The other major deprecation was changing the name of the object on context from “history” to “router”.

This one is tougher. Our motivation here was to make it more clear that you were getting a context object from the router, rather than the history object that you passed into the router. We thought this was cleaner, and wanted to be future-proof in case support for context changed in newer versions of React.

In retrospect, we’re not sure this change accomplished what we wanted it to. Most of the methods you call on the router object are just the methods from the history. If we had to go back, it’s very possible we wouldn’t have made this change, and we’re sorry for any unnecessary inconvenience this may have caused.

Other cool new features

It’s not all breaking API changes, though! The biggest new addition is support for history singletons. You can now do:

This mostly replaces the need for the action creators in older versions of react-router-redux, and gives users who want to avoid the use of React context an easy way to interact with the history object.

That’s all we have for now. We have some cool new features coming in the pipeline. As users of the router, we’re well aware of how painful API changes can be. API stability is important to us, and we try to do the best we can in balancing API stability with improving functionality.

If you have any other questions or concerns, please let us know! We’re always open to suggestions on the issue tracker.