1.3.0 • Published 6 years ago
mobx-state-tree-router v1.3.0
MobX State Tree Router
State-based router for React and MobX State Tree
Inspiration
Installation
Peer dependencies: react react-dom mobx mobx-react mobx-state-tree
NPM: npm install --save mobx-state-tree-router
Yarn: yarn add mobx-state-tree-router
Quick Start
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { RouterStore, View, startRouter, StateRouter, Link } from 'mobx-state-tree-router';
const views = {
home: View.create({
name: 'home',
path: '/',
component: <div>Home page</div>
}),
about: View.create({
name: 'about',
path: '/about',
component: <div>About page</div>
})
};
const router = RouterStore.create({
views: views
});
startRouter(router);
ReactDOM.render((
<div>
<Link router={router} view={views.home}>Home</Link>
<Link router={router} view={views.about}>About</Link>
<StateRouter router={router} />
</div>
), document.getElementById('root'));Features
React components
<StateRouter router loading />- renders the appropriate component for the
router'scurrentView currentViewcan be set by callingrouter.setView(view, params)directly, or using aLinkcomponent- props can be set for the rendered component by calling
router.setProps(props) - a component can be passed into the
loadingprop to display a loading indicator (e.g. ajax spinner)
- renders the appropriate component for the
<Link router view></Link>- renders an
<a href></a>element withhrefset to the result ofview.formatUrl(params)
- renders an
MobX State Tree models
RouterStore- exposes the available
routesbased on theviews - manages the
currentUrlbased on thecurrentViewandparams setView(view, params)can be called to change the routesetProps(props)can be called to pass props to thecurrentView's rendered component
- exposes the available
View- defines a
name,route,componentto render - defines optional change route
hooks:beforeExit(self, params)beforeEnter(self, params)onExit(self, params)onEnter(self, params)
formatUrl(params)can be called to get the url for thisviewgiven theparamspassed
- defines a
Browser url matching and history binding
startRouter(router) binds the router to the browser's history object to update the url or parse a url change and set the appropriate view.
Centralized view definitions
Views and their route cycle hooks (data fetching and business logic) can be defined in one centralized location:
views.js
import { View } from 'mobx-state-tree-router';
import Home from 'components/Home';
import ItemList from 'components/ItemList';
import Item from 'components/Item';
export const views = {
home: View.create({
name: 'home',
path: '/',
component: <Home />
}),
items: View.create({
name: 'items',
path: '/items',
component: <ItemList />
hooks: {
async beforeEnter(self) {
await self.root.itemStore.loadItems();
}
}
}),
item: View.create({
name: 'item',
path: '/item/:itemId',
component: <Item />
hooks: {
async beforeEnter(self, params) {
self.router.setProps({ itemId: params.itemId });
await self.root.itemStore.loadItem(params.itemId);
}
}
})
};Route cycle hooks
These hooks provide a way to run some code during a route change. They can be synchronous or asynchronous. The route change process is as follows:
router.setViewcalledrouter.isLoadingset totrue
- old view
beforeExit(self, params)- returning
falsewill cancel the route change
- returning
- new view
beforeEnter(self, params)- returning
falsewill cancel the route change
- returning
- route is updated and rendered
router.isLoadingset tofalse
- old view
onExit(self, params) - new view
onEnter(self, params)
Known Issues
formatUrldoesn't properly handle paths with catch-all*- current workaround is to use
setViewin thebeforeEnterhook of the catch-all to redirect to another view
- current workaround is to use
- query parameters are not handled