mobx-router

by kitze

A simple router for MobX + React apps

477 Stars 62 Forks Last release: over 1 year ago (v0.0.20) 138 Commits 5 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

πŸ™‹β€β™‚οΈ Made by @thekitze

Other projects:

  • 🏫 React Academy - Interactive React and GraphQL workshops
  • πŸ’Œ Twizzy - A standalone app for Twitter DM
  • πŸ’» Sizzy - A tool for testing responsive design on multiple devices at once
  • πŸ€– JSUI - A powerful UI toolkit for managing JavaScript apps

〽️ MobX Router

Example usage

Inspiration

πŸ“– How to decouple state and UI - a.k.a. you don’t need componentWillMount

Features

  • Decoupled state from UI
  • Central route configuration
  • URL changes are triggering changes directly in the store, and vice-versa
  • No need to use component lifecycle methods like
    componentWillMount
    to fetch data or trigger a side effect in the store
  • Supported callbacks for the routes are:
    beforeEnter
    ,
    onEnter
    ,
    beforeExit
    ,
    onExit
    . All of the callbacks receive
    route
    ,
    params
    ,
    store
    , and
    queryParams
    as parameters. If the
    beforeExit
    or
    beforeEnter
    methods return
    false
    the navigation action will be prevented.
  • The current URL params and query params are accessible directly in the store
    store.router.params
    /
    store.router.queryParams
    so basically they're available everywhere without any additional wrapping or HOC.
  • Navigating to another route happens by calling the
    goTo
    method on the router store, and the changes in the url are reflected automatically. So for example you can call
    router.goTo(routes.book, {id:5, page:3})
    and after the change is made in the store, the URL change will follow. You never directly manipulate the URL or the history object.
  •  component which also populates the href attribute and works with 
    middle click
    or
    cmd/ctrl + click
  • Typescript support (Converted to typescript by thdk)
  • Hash-based routing (using paths like
    /#/foo/bar
    ) support

Implementation

import React, {createContext} from 'react';
import ReactDOM from 'react-dom';

import {MobxRouter, RouterStore, startRouter} from 'mobx-router'; import routes from 'config/routes';

//example mobx store export class AppStore { title = 'MobX Router Example App', user = null }

export class RootStore { public router: RouterStore; public app: AppStore;

constructor() {
    this.router = new RouterStore<rootstore>(this);
    this.app = new AppStore();
}

}

const store = new RootStore();

// Use React context to make your store available in your application const StoreContext = createContext({}); const StoreProvider = StoreContext.Provider;

startRouter(routes, store);

ReactDOM.render( , document.getElementById('root') )

Example config

/config/routes.js

import React from 'react';

//models import {Route} from 'mobx-router';

//components import Home from 'components/Home'; import Document from 'components/Document'; import Gallery from 'components/Gallery'; import Book from 'components/Book'; import UserProfile from 'components/UserProfile';

const routes = { home: new Route({ path: '/', component: }), userProfile: new Route({ path: '/profile/:username/:tab', component: , onEnter: () => { console.log('entering user profile!'); }, beforeExit: () => { console.log('exiting user profile!'); }, onParamsChange: (route, params, store) => { console.log('params changed to', params); } }), gallery: new Route({ path: '/gallery', component: , onEnter: (route, params, store, queryParams) => { store.gallery.fetchImages(); console.log('current query params are -> ', queryParams); }, beforeExit: () => { const result = confirm('Are you sure you want to leave the gallery?'); return result; } }), document: new Route({ path: '/document/:id', component: , beforeEnter: (route, params, store) => { const userIsLoggedIn = store.app.user; if (!userIsLoggedIn) { alert('Only logged in users can enter this route!'); return false; } }, onEnter: (route, params) => { console.log(entering document with params, params); } }), book: new Route({ path: '/book/:id/page/:page', component: , onEnter: (route, params, store) => { console.log(entering book with params, params); store.app.setTitle(route.title); } }) }; export default routes;

Hash-based routing

Just add option for

startRouter
(no need to include
#
in route paths).
js
startRouter(routes, store, {
  html5history: false
});

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.