Routing
In Feature, application are single-page applications, and the page address jumps are done on the browser side, and the server will not be re-requested to html, and html is only loaded once when the application is initialized. All pages are compossed of different components. The switching of pages is actually the switching of different components. You only need to associate different routing paths with corresponding components in the confiugration.
Configuring Routing
Configure through routeConfig
in the configuration file, the format is an array of routing information.
Example:
const genRoutes = [
{
['/ghost']: { component: Component },
['/pepper']: { component: Component, exact: false },
['/pepper/ginger']: { component: Component, exact: true },
['/pepper/:type']: { component: Component, exact: false},
['/pepper/:type/scoville']: { component: Component, exact: false },
},
];
const connector = new Feature({ routeConfig: genRoutes });
path
- Type:
string
path
Only two placeholder configurations are supported, the first is :
in the, and the second is in the form of *
wildcards, which can only appear at the end of the routing string.
component
- Type:
string
Configure the React component.
sub routes
Configure sub-routes by based on the path. In order to have a sub route the parent path should have exact: false
.
Example:
If you need a subroute to /ginger
under pepper
, the parent route /pepper
should have exact: false
and the sub-route should be prepend with parent path like /peper/ginger
const genRoutes = [
{
['/pepper']: { component: Component, exact: false },
['/pepper/ginger']: { component: Component, exact: true },
];
This will result into
const connectorRoutes = connector.getConfiguredRoutes();
/** connectorRoutes = [
{
path: '/pepper',
component: Component,
exact: false,
routes: [
{
path: '/pepper/ginger',
component: Component,
exact: true,
},
],
},
]
**/
redirect
- Type
string
Configure routing jumps.
for example:
const genRoutes = [
{
['/']: { redirect: '/list' },
['/list']: { component: Component, exact: true },
];
const connector = new Feature({ routeConfig: genRoutes });
wrappers
- Type
string[]
wrappers is HOC.
For example, you can run validation check for a specific route.
const genRoutes = [
{
['/user']: {
component: 'user',
wrappers: [ (props) => validationComp ]
},
['/list']: { component: Component, exact: true },
];
title
- Type:
string
Configure the title of the route.
Route component parameters
Feature uses react-router@5
as a routing component. You can use all the routing hooks supported by react-router@5
.
Since routeConfig
is a wrapper of react-router@5
, it supprots all Route Config
Read react-router docs
As well all of react-router@5 APIs are supproted.
Routing Dynamic Parameters
const genRoutes = [
{
['/pepper']: { component: Component, exact: false },
['/pepper/:type']: { component: Component, exact: false},
['/pepper/:type/scoville']: { component: ScovilleComponent, exact: true },
},
];
const connector = new Feature({ routeConfig: genRoutes });
Component
import { useParams } from 'react-router';
const ScovilleComponent = () => {
const params = useParams();
}
/**
for route `/pepper/lime/scoville`
//params
{
"type": "lime"
}
generatePath
Sometimes in a component we need to redirect. The generatePath function can be used to generate URLs to the routes.
import { generatePath, useHistory } from 'react-router';
const ROUTES = {
dashboard: '/o/:orgName/dashboard'
}
const onOrgSelection = (orgName: string) => {
const route = generatePath(ROUTES.dashboard, { orgName: 'test' });
// Will return `/o/test/dashboard`
history.push(route);
};
A realistic app may have Routes configured as below.
Example:
const orgRoutes = {
["/"]: { exact: true, component: MyComponent },
["/login"]: { exact: true, component: MyComponent },
["/callback"]: { exact: true, component: MyComponent },
["/:orgName/usermenu/logout"]: { exact: true, component: MyComponent },
["/:orgName/usermenu/profile"]: { exact: true, component: MyComponent },
["/reset-password"]: { exact: true, component: MyComponent },
["/:orgName/usermenu/account/"]: { exact: false, component: MyComponent },
["/:orgName/usermenu/account"]: { exact: false, component: MyComponent },
["/:orgName/usermenu/account-settings"]: { exact: true, component: MyComponent },
["/:orgName/teams/view/:teamName"]: { exact: false, component: MyComponent },
["/:orgName/teams"]: { exact: true, component: MyComponent },
["/:orgName/invitation"]: { exact: true, component: MyComponent },
["/:orgName/members"]: { exact: false, component: MyComponent },
["/:orgName/dashboard"]: { exact: true, component: MyComponent },
["/:orgName/registries"]: { exact: true, component: MyComponent },
["/:orgName"]: { exact: false, component: MyComponent },
};
Under the hood it will generates to below Object
before passing it to the react-router-config
function.
const reactRouterConfig = [
{
"_pathPrefix": "",
"component": [Function],
"exact": true,
"path": "/authenticate-popup",
"position": "MIDDLE",
},
{
"_pathPrefix": "",
"component": [Function],
"exact": true,
"path": "/callback",
"position": "MIDDLE",
},
{
"_pathPrefix": "",
"component": [Function],
"exact": true,
"path": "/reset-password",
"position": "MIDDLE",
},
{
"_pathPrefix": "",
"component": [Function],
"exact": false,
"name": "rootSlash",
"path": "/",
"position": "MIDDLE",
"routes": [
{
"_pathPrefix": "/",
"component": [Function],
"exact": false,
"path": "/",
"position": "MIDDLE",
},
{
"_pathPrefix": "/",
"component": [Function],
"exact": true,
"path": "/:orgName/dashboard",
"position": "MIDDLE",
},
{
"_pathPrefix": "/",
"component": [Function],
"exact": true,
"path": "/:orgName/invitation",
"position": "MIDDLE",
},
{
"_pathPrefix": "/",
"component": [Function],
"exact": false,
"path": "/:orgName/members",
"position": "MIDDLE",
},
{
"_pathPrefix": "/",
"component": [Function],
"exact": true,
"path": "/:orgName/registries",
"position": "MIDDLE",
},
{
"_pathPrefix": "/",
"component": [Function],
"exact": true,
"path": "/:orgName/teams",
"position": "MIDDLE",
},
{
"_pathPrefix": "/",
"component": [Function],
"exact": false,
"path": "/:orgName/teams/view/:teamName",
"position": "MIDDLE",
},
{
"_pathPrefix": "/",
"component": [Function],
"exact": false,
"path": "/:orgName/usermenu/account",
"position": "MIDDLE",
"routes": [
{
"_pathPrefix": "/",
"component": [Function],
"exact": false,
"path": "/:orgName/usermenu/account/",
"position": "MIDDLE",
},
],
},
{
"_pathPrefix": "/",
"component": [Function],
"exact": true,
"path": "/:orgName/usermenu/account-settings",
"position": "MIDDLE",
},
{
"_pathPrefix": "/",
"component": [Function],
"exact": true,
"path": "/:orgName/usermenu/logout",
"position": "MIDDLE",
},
{
"_pathPrefix": "/",
"component": [Function],
"exact": true,
"path": "/:orgName/usermenu/profile",
"position": "MIDDLE",
},
],
},
]