Client side routing is definitely one of the center piece of gears that empowers single page application. For our React/Redux SPA projects, we have been using redux-little-router that fits in reasonably well. Recently, I had a chance to hand on evaluating and trying out another router package, redux-first-router. Both packages are designed with Redux in mind and so they both work and integrate well with Redux.
At first glance, they both work quite similar by storing the routing info as a state object, trigger routing by dispatching redux action and the browsing history will be taken care by the packages. However, there are some fundamental design and architectural differences that set them apart and as a result, I am in favor of redux-first-router.
State driven (redux-first-router) vs URL driven (redux-little-router)
Both would need to define a list of URLs for routing. For redux-first-router, each URL is also associated with a unique Redux action type and route change is triggered by dispatching the associated action type. For redux-little-router, URL of the route is used to trigger a route change.
Declarative (redux-first-router) vs imperative (redux-little-router)
redux-little-router uses route matching component Fragment to control what react component(s) to display based on the active route URL and/or optional conditions. redux-first-router eliminates the use of route matching component, simply by declaring a mapping the route action type to the react component(s) and use this mapping to pick the right component(s) to display.
No nested routes (redux-first-router) vs nested routes support (redux-little-router)
I believe simplicity always make coding more manageable. Therefore, I have always avoided nested routes even when using redux-little-router.
Support side effect upon route change (redux-first-router)
redux-first-router allows you to declare an optional asynchronous thunk (route thunk) with a route. When a route change occurs, this thunk will be executed. One use is data-fetching which can come in handy.
Advantages of redux-first-router
- No more route URLs all over the places. I came to realize that I did have route URLs all over my codes when using redux-little-router for the simple need of triggering a route change. And any change to route URLs could be a headache.
- With the declarative approach, my route definitions are cleaner and simpler instead of having tons of Fragment components defined.
- The route thunk allows data-fetching ties to the route, instead of triggering inside the react components (in most cases). This is beneficial for server side rendering. When data fetching is triggered inside react components, you would need to call renderToString() twice. First time to initiate all data fetching requests and second time to actually render the component after the data are obtained. Route thunk decouples data fetching and react components and therefore eliminates the need of calling renderToString() twice.
- As far as I have tried, Fragment component from redux-little-router does not work with transitions and is not compatible with react-transition-group. A custom component is needed to support transitions. redux-first-router does not have this limitation.
- Reduced bundle size. By switching from redux-little-router to redux-first-router, I managed to reduce the minified vendor bundle size by about 10KB. The general application code is also reduced by a small faction.
redux-first-router is the way to go if you are looking for a routing solution for React/Redux application.
In the next post I will provide a simple walk-through on using redux-first-router.