Router
Reviewing a React router component implemented with Mosaic for Mosaic
In any frontend or backend application, the router is a place which is one of the most important ones to make plugin-friendly, when using Mosaic. Any amount of routes can be added to it, if it is designed correctly.
This article will demonstrate a router design from @scandipwa/shopify project, which is written completely in Mosaic.
Source implementation
Let's see the router itself! It is also available on this link. This is exactly the form of the router at the moment of writing this article.
It is clearly visible that the router does not actually render any routes! It just provides several convenient points for modification with Mosaic runtime plugins: _beforeSwitchRenderList
, _switchRenderList
and _afterSwitchRenderList
import { createSortedRenderMap } from '@scandipwa/framework/src/util/SortedMap';
import { createBrowserHistory } from 'history';
import { PureComponent } from 'react';
import { Router as ReactRouter } from 'react-router';
import { Switch } from 'react-router-dom';
export const history = createBrowserHistory({ basename: '/' });
/** @namespace Router/Component/Router/Component/RouterComponent */
export class RouterComponent extends PureComponent {
static propTypes = {};
_beforeSwitchRenderList = createSortedRenderMap({});
_switchRenderList = createSortedRenderMap({});
_afterSwitchRenderList = createSortedRenderMap({});
contentRenderList = createSortedRenderMap({
routerBeforeSwitch: this._beforeSwitchRenderList.render,
routerRenderSwitch: this.renderSwitch.bind(this),
routerAfterSwitch: this._afterSwitchRenderList.render
});
renderSwitch() {
return (
<Switch>
{ this._switchRenderList.render() }
</Switch>
);
}
renderRouterContent() {
return this.contentRenderList.render();
}
render() {
return (
<ReactRouter history={ history }>
{ this.renderRouterContent() }
</ReactRouter>
);
}
}
export default RouterComponent;
Filling such a router by using plugins
A router is pointless without routes, right? So let's add a route to the one defined above! We will use the Mosaic runtime plugins for this purpose.
As you see, the plugin declaration file presented below modifies the namespace of the class above, a member called _switchRenderList
of target kind member-property
It implements a plugin (proxy) function addCartPage
, which accepts the initial member - sorted render map _switchRenderList
declared above, adds an additional item to that map and returns the modified value to the application.
/* eslint-disable @scandipwa/scandipwa-guidelines/jsx-no-props-destruction */
import { createElement, lazy, Suspense } from 'react';
import { Route } from 'react-router';
import CartFallbackPage from '../component/CartFallbackPage';
const CartPage = lazy(() => import('../component/CartPage'));
const addCartPage = (member) => {
const CART_PAGE_POSITION = 1000;
member.addItem(
() => createElement(Route, {
path: '/cart',
exact: true,
render: (props) => (
<Suspense fallback={ <CartFallbackPage /> }>
<CartPage { ...props } />
</Suspense>
)
}),
'routerCartPage',
CART_PAGE_POSITION
);
return member;
};
export default {
'Router/Component/Router/Component/RouterComponent': {
'member-property': {
_switchRenderList: addCartPage
}
}
};
Last updated
Was this helpful?