Redux sagas and URLs

Once you add redux simple router (or redux router) to your project you have two places in your state that need to be kept in sync.

import { combineReducers } from 'redux'
import { routeReducer } from 'redux-simple-router'
import tree from './tree'

const rootReducer = combineReducers({
tree: tree,
routing: routeReducer

export default rootReducer

Now every time you change tree you need to update the routing part. That’s easy because your action creators may push a new state into the browser history.

The other way around, -changing the URL and reduce correctly- is a bit more complex because the router dispatches only one action (UPDATE_LOCATION if using redux-simple-router) and based on this action you need to reduce your state correctly.

Matching -and sometimes parsing- the url in your reducers is something that feels wrong, it is a logic that doesn’t belong to the reducer.

Redux Sagas

Sagas in redux are a way to listen for redux actions and spawn side effects accordingly and because url changes and async requests can be treated as side effects I created a saga to handle both.

The first saga retriveNode watches for the RETRIEVE_NODE action that I dispatch on the connected components, once the action is fired it executes in order some side effects, one of them being the url change provided by the push function.

Now we need to tackle another problem, what happens when someone changes the url like as a result of clicking the back or forward button on the browser?

In that case, the routing part of our state changes but the tree part remains the same. The solution is in the last saga called urlChanged.

I listen to the UPDATE_LOCATION action and check if this action has been a POP, a POP action is our way to say: Did this action occur has a result of a back / forward navigation? This is because I don't want to react to url pushes made from the previous saga.

Once the url changed as a result of the back / forward button we send the action to retrieve the node, this will wake up the retriveNode saga and rebuild our state correctly.