Router5 integration with mobx. If you develop with React, use this package with react-mobx-router5. This plugin represents the source of truth for the @observer components exposed by react-mobx-router5.
This plugin can also be used standalone together with mobx.
Notice Mobx@5 introduced breaking changes, please follow the migration guide
These are considered peerDependencies
that means they should exist in your installation, you should install them yourself to make this plugin work. The package won't install them as dependencies.
npm install mobx-router5
Before using this plugin it is necessary that you understand how router5 works.
Whenever you performs a router5's transition from one state to another and that transition is started, canceled, it's successful or it has a transition error
this plugin exposes all this info as mobx observables references properties of the RouterStore
class.
You can then use the mobx API to observe and react to these observables:
@observable.ref route; // Current Route - Object
@observable.ref previousRoute; // Object
@observable.ref transitionRoute; // Object
@observable.ref transitionError; // Object
@observable.ref intersectionNode; // String
@observable.ref canActivate; // Array
@observable.ref canDeactivate; // Array
RouterStore
class navigate
that is just an alias for router5 navigate
import {createRouter} from 'router5';
import loggerPlugin from 'router5/plugins/logger';
import browserPlugin from 'router5/plugins/browser';
import routes from './routes';
import {mobxPlugin, RouterStore} from 'mobx-router5';
// Instantiate it directly or extend the class as you wish before invoking new
const routerStore = new RouterStore();
export default function configureRouter(useLoggerPlugin = false) {
const router = createRouter(routes, {defaultRoute: 'home'})
.usePlugin(mobxPlugin(routerStore)) // Important: pass the store to the plugin!
.usePlugin(browserPlugin({useHash: true}));
if (useLoggerPlugin) {
router.usePlugin(loggerPlugin) ;
}
return router;
}
The core idea of this little plugin is the router store.
The plugin will automatically call the actions (in fact mobx @action
s) exposed by the store.
By default you can just import the class RouterStore
, create a new instance, pass it to the plugin and just use it.
On route transition Start/Success/Cancel/Error the mobxPlugin invokes automatically these mobx actions exposed by the RouterStore
:
onTransitionStart(toState, fromState)
transitionRoute
transitionError
onTransitionSuccess(toState, fromState, opts)
route
, previousRoute
, canActivate
, canDeactivate
and interserctionNode
clearErrors()
action onTransitionCancel(toState, fromState)
transitionRoute
onTransitionError(toState, fromState, err)
transitionRoute
, previousRoute
and transitionError
Normally it's not necessary to manually call these actions, the plugin will do it for us.
The only one probably worth calling manually (only when necessary) is clearErrors()
: it resets the transitionRoute
and transitionError
.
When you add the plugin to the router with
router.usePlugin(mobxPlugin(routerStore))
the router reference is added to the store, so that you can call all the router's methods from the store itself, for example:
routerStore.router.navigate('home', {}, {})
and all other router5's API listed here.
The plugin also adds the routerStore
(the instance) to the router dependencies with
router.setDependency('routerStore', routerStore);
That means that you can access your store from router5's lifecycle methods (canActivate, canDeactivate), middleware or plugins, see router5 docs on this topic.
This creates indeed a cross referece, that is, the store has a reference of the router and the router has a reference of the store. In most cases this should not create any trouble but be aware of this for cases I haven't foreseen.
If you know what you are doing you can subclass or create yor own store, making sure you implement at least the actions listed above and a setRouter(router)
method.
Please refer to the CONTRIBUTING.md file.
Please notice that this would require node >=8 as some dev packages require it (for example semantic-release)