Static route mapping for React Router

React Router Chart

Create a single source map of truth for all routes in your react app and easily render in react-router.

Getting Started

Install

Include in your dependencies.

npm install 'react-router-chart'

Use react-loadable to separate component logic from route mapping, by deferring the load of the component to the time of render.

npm install 'react-loadable'

API Reference

The Route Object

This is what defines a mapping of ReactRouter objects. Should not be confused with react-router/Route.

Shapes

// https://reacttraining.com/react-router/web/api/Route
type ReactRouterRouteProps;

// https://reactjs.org/docs/components-and-props
type AnyObject;

// Used to initialise the Route object.
export interface RouteShape {
    name?: string;
    props?: ReactRouterRouteProps;
    renderProps?: AnyObject;
    suffixes?: Suffixes;
    nest?: {
        props?: ReactRouterRouteProps;
        renderProps?: AnyObject;
        routes?: RouteShape[];
    };
}

// Object with values as the path suffix and keys as path names.
export interface Suffixes {
    [name: string]: string;
}

Methods

These methods on the route. Most return a reference to the updated object for easier mapping.

setName(String): Route

Sets route.name and returns updated object for chaining. This is the value used for describing directions, therefore must be unique in the context of its parent route.

setProps(Object): Route

Sets route.props and returns updated object for chaining. See add props to apply a partial update.

addProps(Object): Route

Updates route.props and returns updated object for chaining. Accepts all react-router/Route props, using path as the base for suffixes when rendered.

rPath(String): Route

Sets route.props.path and returns updated object for chaining.

rkey(String): Route

Sets route.props.key and returns updated object for chaining.

This is passed to any rendered react-router/Route as the key prop.

rExact(Boolean): Route

Sets route.props.exact and returns updated object for chaining.

rStrict(Boolean): Route

Sets route.props.strict and returns updated object for chaining.

rLocation({ pathname }): Route

Sets route.props.location and returns updated object for chaining.

rSensitive(Boolean): Route

Sets route.props.sensitive and returns updated object for chaining.

rChildren(Function)

Sets route.props.children and returns updated object for chaining.

rComponent(ReactComponent): Route

Sets route.props.component and returns updated object for chaining.

rRender(Function): Route

Sets route.props.render and returns updated object for chaining.

setRenderProps(Object): Route

Sets route.renderProps. Extra properties passed to the render of this route. When this is non empty react router render property is always used.

setSuffixes(Suffixes): Route

Sets route.suffixes. Named paths appended to base, result used as value of react-router/Route path prop. Supports multiple suffixes each with unique keys.

addSuffixes(Suffixes): Route

Updates existing route.suffixes with one or more suffixes.

removeSuffixes(...String): Route

Updates existing route.suffixes, takes a list of names, used as keys to delete matching path suffixes. Returns updated object for chaining.

setNestedProps(Object): Route

Sets route.nest.props, optional base props passed to all children routes. This is equivalent to adding to the route.props of all nested Route.

setNestedRenderProps(Object): Route

Sets route.nest.renderProps, optional extra properties passed to the render of all children routes. This is equivalent to setting the route.renderProps of all nested Route.

setNestedRoutes(Route[]): Route

Sets route.nest.routes, the list of children routes. Will generates react-router/Route for every base and suffix combination.

addNestedRoutes(...Route): Route

Updates route.nest.routes, adding any number of routes to the existing list of nested routes.

removeNestedRoutes(...String): Route

Updates route.nest.routes, taking a number of route names and removeing from list of routes. This only works on named nested routes.

render(): ReactRouter.Route[]

Generate and return all the react-router/Route components.

describe(): RouteDirection

Generate easily accessible directions to all named paths.

export type RouteDirection = {
    [$: string]: string;
};

Usage

See example below.

The Chart Object

This is the library main export. See example below for more detailed usage.

Static Methods

Exposes two covenience methods, for initialising the rendering the route map.

route(RouteShape)

Create a Route object with the specified shape (see shape above). Equivalent to calling new Route(routeShape).

const route = Chart.route({
    name: "base",
    props: {
        path: "/",
        component: App,
        strict: true,
    },
});

route.name;         // "base"
route.props;        // { path: "/", strict: true }
route.describe().$; // "/"
render(Route):

Renders a given route object. Equivalent to calling route.render().

Chart.render(route);
// generates
<Route path="/" component={App} strict />;

Example

In route definition files

import { Chart } from "react-router-chart";

Start charting routes

const childRoute = Chart.route({
    props: { path: "/iam", component: ChildView, key: "a-child-view" },
    suffixes: { aChild: "/a/child" },
}).setRenderProps({ level: 2 });

const parentRoute = Chart.route({
    props: { exact: true, strict: true, component: BaseView },
    suffixes: { example: "/example/:id", demo: "/demo/:id" },
    renderProps: { highlight: true },
})
    .addNestedRoutes(childRoute)
    .setNestedProps({ exact: true, strict: true })
    .setNestedRenderProps({ highlight: true, level: 1 });

const baseRoute = Chart.route({
    name: "base",
    props: { path: "/mybase" },
    nest: { routes: [parentRoute] },
});

In main app with react router

<Switch>{ baseRoute.render() }</Switch>

Equivalent to

<Switch>
    <Route
        path="/mybase/example/:id"
        key="/mybase/example/:id"
        exact
        strict
        render={ props => <BaseView highlight=true {...props} /> }
    />
    <Route
        path="/mybase/demo/:id"
        exact
        strict
        render={ props => <BaseView highlight=true {...props} /> }
    />
    <Route
        path="/mybase/example/:id/iam/a/child"
        key="a-child-view.0"
        exact
        strict
        render={ props => <ChildView highlight=true level=2 {...props} /> }
    />
    <Route
        path="/mybase/demo/:id/iam/a/child"
        key="a-child-view.1"
        exact
        strict
        render={ props => <ChildView highlight=true level=2 {...props} /> }
    />
</Switch>

Get directions to all named routes

const paths = route.describe();

Easily access location path

paths.$;                // "/mybase"
paths.demo.$;           // "/mybase/demo/:id"
paths.example.$;        // "/mybase/example/:id"
paths.demo.aChild.$;    // "/mybase/demo/:id/iam/a/child"
paths.example.aChild.$; // "/mybase/example/:id/iam/a/child"

Can be used in snapshots to verify generated routes.

GitHub