Thinking of State in a World of URLs
An intro to Redux-Location-State
Like most of the web community, Spotify has found the combination of React and Redux to be a super powerful tool. It has allowed us to iterate quickly, build powerful components that can be shared across development teams, and onboard new developers much faster than previously. While we generally love what these tools have given us, there have been several things that we’ve had to work around. One of those things is the url, which is why we built redux-location-state.
What is it?
Redux-location-state, shortened to RLS, is Redux middleware that’s plugged into your Redux store that tracks pieces of state based on a url. You declare the parts of state you want in your url, what type it is, and what url it maps to. Then, when that part of the store is updated, it will be reflected in the url using a consistent mapping method. When a user changes the url via the back or forward buttons, RLS will allow users to map the url state to the Redux store.
Originally this project came about from the discussion on this issue. The idea of single source of truth is a great one with small to no side effects, and you know where you need to check to see the current state. Those who used other storing methods in the past can tell great war stories of a fragmented source of truth. Unfortunately we also live in a world where a user wants to go back, save a url, or send it to a friend. The question is then, where is your single source of truth? The url or the Redux store? RLS was created to make both of those as close to one and the same as possible.
A deeper dive:
It starts with declaring which state you’d like to keep on the url. Obviously it’s a potentially bad thing to keep everything on the url, so declare which parts of state you’d like to keep for which url, and which you’d like to keep regardless of the url (a global variable). The initial state will load if nothing is in the url, and your url will also be cleaned up if state is in its initial state.
Then, when you initialize your Redux store you inject RLS into your reducers like above. And that’s it for keeping your state on the browser! You’ll notice you pass in a function that maps the location query back into the state. We debated for a long time on whether or not to do this automagically, but there are some teams that like to use immutable.js or tcomb in their store and we wanted users to be able to use whatever they’d like.
There are a lot of options that we’ve included, like the ability to replace instead of push to history, to map and parse manually, and a variety of other things. V1.0 was built for react-router v3, whereas 2.0 is built for react-router v4. Huge thanks to Dan Delany and Sam Walker for an early vision and build of this. Here’s to urls to be more stateful!