React Router Outlet - Angular-inspired router outlet for React Router
npm install react-router-outletReact Router Outlet provides a very simple, declarative way to define your React Router routes, inspired by Angular's approach.
This library requires React Router v5 as peer dependency.
To enable routing, the app would have a instance at a top-level component, ideally the . You will only need to have one such instance for the entire app. This is provided by the standard React Router, not this library. You can check the React Router official documentation for details.
This library provides a _router outlet_ component that dynamically changes content depending on the current route. This is a convenient drop-in replacement for React Router's combination of , and components, and then adds a couple of neat features as well.
Place this component wherever you need routed views.
``html`routes
where defines the routes declaratively (see below).
Routing can apply to any level component, so you can place a virtually anywhere in the component tree. Similarly, you can have as many nested router outlets as required in the application, particularly when your route paths go from wildcard to specific.
IMPORTANT: If your and the are not in the same parent component, you would normally need to apply React Router's withRouter HOC to the component that renders the . This is a requirement of React Router, not of Outlet, so please check their documentation for details.
We use this format when declaring routes:
`javascript`
const routes = [
{
path: '/login',
component: LoginPage
},
{
path: '/default',
component: DefaultPage
},
{
path: '/',
exact: true,
redirectTo: '/default'
},
{
component: NotFound
}
];
These are the common cases for routes:
- Both path and component are defined in the route spec. This is straightforward routing.path
- No is specified, which means this is the default route if none of the preceding routes matched.exact
- If is set to true, the path has to match exactly.redirectTo
- If path is specified instead of component, this is a straightforward redirection.
Sometimes you need to restrict access to certain routes depending on some conditions. In such cases, you can do something like this:
`javascript`
{
path: '/default',
component: DefaultPage,
canEnter: isAuthenticated,
fallback: '/login',
},`javascript`
const isAuthenticated = ({ auth }) => auth !== null;
If a canEnter _guard function_ is defined, the router will only activate the matched route if this function evaluates to true. Otherwise, it will route to the fallback path. This is useful for apps that require user login to access specific features. Just make sure to define fallback whenever you have a canEnter.
The signature of such guard function is:
`typescript`
(outletProps: Object, route: Object) => condition: booleanoutletProps
where contains all props that were passed to , while route is a reference to the matched route.
In the example above, the outlet would look like this:
`html`auth
so that the prop is passed to the isAuthenticated guard.
If you pass some _state_ value (or an injected _state prop_, either internal or from store), the will re-render, hence routing will happen, whenever this state value changes.
Both redirectTo and fallback in your routes can alternatively be expressed as functions with the following signature:
`typescript`
(outletProps: Object, route: Object) => path: string
In this case, these path values are only evaluated when the renders, and therefore you can dynamically determine the target paths based on props that were passed to the outlet, similar to how canEnter works with such props.
For example:
`javascript`
{
path: '/login',
redirectTo: ({ referrer }) => referrer
}referrer
where is a prop of the outlet:`html`
For optimization, feature components can be _lazy loaded_, i.e. they are only fetched by the browser if and when they are required by the app. This technique is also called _code splitting_.
Instead of the normal import, use React Lazy to import lazy-loaded components.
`javascript
import React, { lazy } from 'react';
const WelcomePage = lazy(() => import('../welcome/WelcomePage'));
`
Then you can optionally tell to display a placeholder (e.g. a spinner component) while the component is being loaded. For example:`html
where placeholder can be any component.The
For more information on React Lazy and Suspense, check out the official documentation.