Skip to content

kitze/mobx-router

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

153 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ™‹β€β™‚οΈ 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

Zero To Shipped


〽️ 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.
  • <Link> 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<RootStore>; 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( <StoreProvider value={store}> <MobxRouter store={store}/> </StoreProvider>, 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: <Home/> }), userProfile: new Route({ path: '/profile/:username/:tab', component: <UserProfile/>, 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: <Gallery/>, 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: <Document/>, 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: <Book/>, onEnter: (route, params, store) => { console.log(`entering book with params`, params); store.app.setTitle(route.title); } }) }; export default routes;

Custom director configuration

mobx-router uses director behind the scenes. mobx-router exposes the director config object for you to pass your own configuration to director.

To do this you must pass a DirectorConfig object as third argument of startRouter method.

Hash based Routing | html5history

If you disable html5history option, mobx will fallback to hash based routing.

startRouter( routes, store, { // https://github.com/flatiron/director#configuration html5history: false, } );

Not found (404) route | notfound

You can pass a function to notfound which will be called when you don't have any matching route for the current path.

startRouter( routes, store, { // https://github.com/flatiron/director#configuration notfound: () => store.router.goTo(YOUR_NOT_FOUND_ROUTE), } );

About

A simple router for MobX + React apps

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors