MobX State Router

MobX State Router

  • Docs
  • GitHub

›Guides

Guides

  • Getting Started
  • Recipes
  • Examples

API

  • Route
  • RouterLink
  • RouterState
  • RouterStore
  • RouterView
  • HistoryAdapter
  • StaticAdapter

Recipes

This section describes mobx-state-router recipes for some common routing scenarios.

Fetching Data

As mentioned before, UI should not be responsible for fetching data. This means no data fetching in componentWillMount() or componentDidMount(). Lately React allows fetching data using hooks, which is somewhat better. However, mobx-state-router facilitates data fetching completely out of the view hierarchy. You can do this using the onEnter transition hook. This hook is called just before a new router state is entered and is the perfect place to kick off a data fetch. Here's an example from MobX Shop:

{
    name: 'department',
    pattern: '/departments/:id',
    onEnter: async (
        fromState: RouterState,
        toState: RouterState,
        routerStore: RouterStore
    ) => {
        const { rootStore } = routerStore.options;
        const { itemStore } = rootStore as RootStore;
        itemStore.loadDepartmentItems(toState.params.id);
    },
},

This code is part of route definitions. We define an onEnter hook that calls itemStore.loadDepartmentItems() to kick off the fetching process. The hook does not have to wait for the fetch to complete (note no await). The itemStore can maintain state to indicate the status of the fetch. After calling itemStore.loadDepartmentItems(), the hook returns, allowing the router proceed to the target state.

Redirecting to the Sign In page

If the user is not logged in, we can direct them to a Sign In page. Not only that, we can direct them back to the requested page upon a successful sign in. For example, in MobX Shop, we allow the user to add items to the shopping cart without having to sign in. However they can't proceed to checkout unless signed in. This is achieved by using the beforeEnter hook in the route configuration. Here's the code from MobX Shop:

{
    name: 'checkout',
    pattern: '/checkout',
    beforeEnter: checkForUserSignedIn
}

checkForUserSignedIn() is a shared transition hook used by multiple routes. It is defined in the routes.js file:

const checkForUserSignedIn = async (
    fromState: RouterState,
    toState: RouterState,
    routerStore: RouterStore
) => {
    const { rootStore } = routerStore.options;
    const { authStore } = rootStore as RootStore;
    if (!authStore.user) {
        authStore.setSignInRedirect(toState);
        return signin;
    }
};

This hook allows the router to proceed if the user is already signed in. If not, the requested state is saved in authStore and the app is redirected to the signin state. On a successful sign in, authStore redirects the app to the originally requested state. Here's the code from MobX Shop:

setUser = (user: User) => {
    this.user = user;
    this.rootStore.routerStore.goToState(this.signInRedirect);
};

Creating Links

You will notice that anchor tags used for linking to internal pages cause a flicker when clicked. That's because such links reload the entire app! We need to prevent the default handling of these links and let the router handle the redirects. This can be done using the <RouterLink> component provided by the router. Here's an example of a page header with links to the Home and About pages:

import React from 'react';
import { RouterLink } from 'mobx-state-router';
import './Header.css';

export const Header = () => (
    <header>
        <ul className="navbar">
            <li>
                <RouterLink routeName="home" activeClassName="link--active">
                    Home
                </RouterLink>
            </li>
            <li>
                <RouterLink routeName="about" activeClassName="link--active">
                    About
                </RouterLink>
            </li>
        </ul>
    </header>
);

RouterLink accepts className and activeClassName as optional properties. className is always applied to the generated anchor tag. activeClassName is applied in addition if the current routerState matches the state specified by the RouterLink. This feature is useful for highlighting the active link in a navbar.

← Getting StartedExamples →
  • Fetching Data
  • Redirecting to the Sign In page
  • Creating Links
Copyright © 2021 Naresh Bhatia