mr-router5 uses Router5 together with MobX for your favorite React application.
router5
is an awesome framework and view library agnostic router.MobX
is a battle tested library that makes state management simple and scalable by transparently applying functional reactive programming.
mr-router5 creates a minimal bridge between router5, MobX and React. When I say 'minimal bridge', I really mean it. Your React components stay untouched, there's no need to create HOC for your root App component. The global and route level payload makes the route transition more flexible and powerful.
React
>=16.8router5
^7 || ^8mobx
^6mobx-react-lite
^3
npm install --save mr-router5
v4
removes the RouteTree
class, the upgrade should be straightforward.
// v3
import { RouteTree, routerStore, initMrRouter5 } from "mr-router5";
const routeTree = new RouteTree([...]);
const router = createRouter(routeTree.getRoutes(), {});
initMrRouter5(router, routeTree);
// v4
import { routerStore, toRoutes } from "mr-router5";
const routeViews = [...];
const router = createRouter(toRoutes(routeViews), {});
routeStore.init(router, routeViews);
see router5 on how to create router instance.
import React from "react";
import { render } from "react-dom";
import createRouter from "router5";
import { RouteComponent, RouteView, routerStore, toRoutes } from "mr-router5";
// define components.
const Home = () => <div>'home' component</div>;
const UserNode = () => <div>'user' route node component</div>;
const UserList = () => <div>'user list' component</div>;
const UserView = () => <div>'user view' component</div>;
// define route views. NOTE, only flat routes are supported.
const routeViews = [
new RouteView({name: "home", path: "/"}, Home),
new RouteView({name: "users", path: "/users"}, UserNode),
new RouteView({name: "users.list", path: "/list"}, UserList),
new RouteView({name: "users.view", path: "/view"}, UserView),
];
// create router instance and initialize mr-router5.
const router = createRouter(toRoutes(routeViews), {});
routeStore.init(router, routeViews);
// create root route node.
const routeNodeName = ""; // THIS NAME MUST MATCH THE ROUTE NAME! (empty string for root route node)
const RootNode = () => (
<div>
<h2>Header</h2>
<RouteComponent routeNodeName={routeNodeName} />
<h4>Footer</h4>
</div>
);
// start the router.
router.start(() => {
render(<RootNode />, document.getElementById("app"));
});
You can add payload to each route view, by setting extra
and dataLoader
. There are many ways to use them, one example would be middleware, see router5 middleware.
const routeViews = [
new RouteView({name: "login", path: "/login"}, Login),
new RouteView({name: "user", path: "/user"}, UserComponent)
.setExtra("user", "John Doe")
.setExtra("requireLogin", true)
.setDataLoader("getUserDetail", (user) => ({ /* user details */ }))
];
// router5 middleware
router.useMiddleware((router) => (toState, fromState, done) => {
// get route view of the toState
const rv = routerStore.getRouteView(toState.name);
// skip login check if 'requireLogin' is false.
if (!rv.getExtra("requireLogin", false)) {
done();
}
else {
// check if user is logged in
const isLoggedIn = true;
if (isLoggedIn) {
const user = rv.getExtra("user");
const userDetail = rv.getDataLoader("getUserDetail")(user);
done();
}
else {
done({ redirect: { name: "login" } });
}
}
});
That's it. Enjoy routing.