@davidjcastner/router v1.0.0
Router
front end router for react apps
How to use
import type { FunctionComponent } from 'react';
import type { RouteDefinition } from '@davidjcastner/router';
import React from 'react';
import { RoutePage, RouteRegistry } from '@davidjcastner/router';
// import all pages
const HomePage: FunctionComponent = () => <div />;
const AccountPage: FunctionComponent = () => <div />;
const OtherPage: FunctionComponent = () => <div />;
const NotFoundPage: FunctionComponent = () => <div />;
// authentication
const SignInForm: FunctionComponent = () => <div />;
// all route definitions
// TIP: use an enum for route names
// routes default to isPublic: false
const routes: Array<RouteDefinition> = [
{
route: 'home',
component: HomePage,
path: [],
isPublic: true,
},
{
route: 'account',
component: AccountPage,
path: ['account'],
},
{
route: 'other',
component: OtherPage,
path: ['other', 'path'],
tokenCount: 1,
},
];
// App - root Component
// render or export App component
export const App: FunctionComponent = () => {
// use authentication method to get a user
// user/signin is optional (leave all routes public)
const user = null;
// wrap RoutePage with RouteRegistry
// can add layout here or on each page
return <RouteRegistry routes={routes} >
<RoutePage
notFound={NotFoundPage}
signIn={SignInForm}
isSignedIn={Boolean(user)} />
</RouteRegistry>;
};
Types
RouteDefinition
/** information required for registering a route */
export type RouteDefinition = {
/** internal name used for router */
route: string;
/** react component to render as route page */
component: FunctionComponent;
/** url path segments for route */
path: Array<string>;
/** whether or not a user must be logged in to see page - default: false */
isPublic?: boolean;
/** number of token segments on end of path - default: 0 */
tokenCount?: number;
};
RouteInformation
/** information from parsed url */
export type RouteInformation = {
/** internal name used for router */
route: string;
/** tokens on end of path */
tokens: Array<string>;
/** key value pairs from query string */
query: Record<string, string>;
/** string appended by hash */
hash: string;
};
RouteState
/** values available in router/location context */
export type RouteState = Required<RouteDefinition> & Omit<RouteInformation, 'route'>;
LocationContext
/** values available in router/location context */
export type LocationContext = {
/** internal name used for router */
route: string;
/** url path segments for route */
path: Array<string>;
/** tokens on end of path */
tokens: Array<string>;
/** key value pairs from query string */
query: Record<string, string>;
/** string appended by hash */
hash: string;
/** whether or not a user must be logged in to see page - default: false */
isPublic: boolean;
/** react component to render as route page */
component: FunctionComponent;
/** utility function for constructing a relative href based on route info */
pathForRoute: (info: Partial<RouteInformation>) => string;
/** utility function for directing to a relative href based on route info */
goToRoute: (info: Partial<RouteInformation>) => void;
};
Components
RouteRegistry
Wrap application with RouteRegistry to provide all children with location context. When using authentication context, the RouteRegistry should be place inside of the authentication context.
export const RouteRegistry: FunctionComponent<{
routes: Array<RouteDefinition>;
}>;
RoutePage
RoutePage renders the component that was registered for the current route. RoutePage must be within a RouteRegistry component. If the current route, does not match a registered definition, then the notFound component is rendered. If the route is private and isSignedIn is false, then the signIn component is rendered.
export const RoutePage: FunctionComponent<{
notFound?: FunctionComponent;
signIn?: FunctionComponent;
isSignedIn?: boolean;
}>;
Link
Link adds a link to the page with the correct relative href for the route specified. RoutePage must be within a RouteRegistry component. Additional css classes can be added or an action to complete after being clicked.
export const Link: FunctionComponent<{
route: string;
tokens?: Array<string>;
query?: Record<string, string>;
hash?: string;
className?: string;
afterClick?: (() => void) | null;
}>;
Context
useLocation
useLocation provides information about the current route to any child component of a RouteRegistry. See LocationContext for details.
Utility Functions
/** utility function for getting path of current route */
export const getPath = (
pathname: string = window.location.pathname
) => Array<string>;
/** utility function for getting hash of current route */
export const getHash = (
hash: string = window.location.hash
) => string;
/** utility function for getting query of current route */
export const getQuery = (
search: string = window.location.search
) => Record<string, string>;
/** constructs the relative href for the given parameters */
export const pathFor = ({
path = [],
query = {},
hash = '',
}: {
path?: Array<string>;
query?: Record<string, string>;
hash?: string;
}) => string;
/** goes to the relative page */
export const goTo = ({
path = [],
query = {},
hash = '',
}: {
path?: Array<string>;
query?: Record<string, string>;
hash?: string;
}) => void;
4 years ago