by Eugen Kiss

How to route like a hacker with MobX and router5

Routing that fits your app — not the other way round

Photo by Rob Bates on Unsplash

There are many ways to approach routing in client-side apps. Frameworks like Android provide powerful but also complex and sometimes restrictive routing mechanisms. The same applies to full-fledged routing libraries in the frontend like React Router.

The good news is that you can write your own routing layer that is simpler without giving up control: Routing that fits your app—not the other way around!

To illustrate these concepts, let’s write a HackerNews app and take control of routing. We will use React, MobX and router5.

This is the live result:

The example uses HNPWA API. Here’s the Github project.

Let’s start by defining the Feed route:

The properties name, path, and comp are obvious. With link you have type-assisted reverse routing. In the lifecycle function activate , you update global state and perform API requests. The dependency store is your central state management and action control panel. In the last line, you add FeedRoute to your route registry routes.

The cool thing about FeedRoute is that everything relevant for routing to/from the Feed screen is defined in one place. Plus, you don’t need a container component for performing API requests.

Here’s how you render the current route:

The observable property store.route contains the current route. In your route registry store.routes you find the corresponding route definition. So, you know which component to render. If you’re on / the component will be <FeedScreen/>. By being an observer, App rerenders whenever the observable store.route changes.

That’s the gist!

Getting it set up

How do you set all this up with MobX and router5? Who updates the current route? What does store look like? To find out, read on!

Aside: Although a routing library is not required, I do recommend router5. It gives you a more convenient API (+ hooks and utilities) than the browser’s native one.

The router5 plugin definition:

A router5 plugin implements lifecycle functions. On a successful transition, you deactivate the previous route. Then you set store.route to the next route and activate the next route. Deactivation performs cleanup. Activation performs API requests and other initialization logic. The rest of the code is router5 API specific.

Here are the relevant parts from store:

The selected feed is derived from the URL. There is no duplication of state thanks to MobX’s propagation power!

Aside: I use a special fetching helper which will be a topic for another article.

In my own HackerNews client (live), a history stack keeps track of the visited routes. It is used to render the screens on top of each other. All but the top-most screen have display set to none. This makes going back to the previous screen on mobile devices much faster!

My router also performs view state restoration. Think scroll position. But you can just as well keep it as minimal as shown here. Remember, you are in control of routing: do it in a way best suited to your app. See also React Router’s scroll restoration discussion and router5’s loading async data dicussion.

The presented approach is inspired by:

If you enjoyed this article, please recommend and share. Happy Routing!