@anansi/router
TypeScript icon, indicating that this package has built-in type declarations

0.9.5 • Public • Published

@anansi/router

npm downloads bundle size npm version PRs Welcome

A simple router designed for React 18 concurrent mode.

  • Automatic code splitting
  • Parallel fetch
    • JS code
    • CSS code
    • images
    • data
  • Take advantage of Suspense with Concurrent rendering
    • Fetch-as-you-render
Slow network Sorry, your browser doesn't support embedded videos.

Parallel fetches

  • JS code
  • CSS code
  • images
  • data
Fast network Sorry, your browser doesn't support embedded videos.

Even though all the data must be fetched - it appears instant because React delays rendering until the resources are available.

import { Controller, useController } from '@data-client/react';
import { createBrowserHistory } from 'history';
import { lazy, Route, RouteController, RouteProvider } from '@anansi/router';

const lazyPage = (pageName: string) =>
  lazy(() => import(/* webpackChunkName: '[request]' */ `pages/${pageName}`));

const routes: Route<Controller>[] = [
  { name: 'home', component: lazyPage('Home') },
  {
    name: 'posts',
    component: lazyPage('Posts'),
    resolveData: async ({ fetch }: Controller) => fetch(PostResource.list(), {}),
  },
];

const history = createBrowserHistory();

export const router = new RouteController({
  history,
  namedPaths,
  routes,
  notFound: { component: NotFound },
});

export function Router({ children }: { children: React.ReactNode }) {
  const controller = useController();
  return (
    <RouteProvider
      initialPath={globalThis.location.pathname}
      router={router}
      resolveWith={controller}
    >
      {children}
    </RouteProvider>
  );
}

API

type Route

interface Route<ResolveWith, Match = any> {
  name: string;
  component: React.ComponentType<any>;
  resolveData?: (
    resolveWith: ResolveWith,
    match: Match & Route<ResolveWith, Match>,
  ) => Promise<void>;
}

name: string

Identifies the route

component: lazyComponent

Component to render when this route matches

resolveData?

resolveData is called when a location change occurs. Use this to prime your networking cache with data needed for this route's components.

The resolution marks completion of a React concurrent transition.

The first argument passed will be whatevever you passed to the &lt;RouteProvider/>'s resolveWith. This helps with dispatchers whose lifetime is restricted to React.

... more

Additional members can be defined and will be passed as props to the component.

lazy(() => Promise<{ default: Component }>)

Like React.lazy() but built for fetch-as-you-render as well as being memo'd.

Component will be rendered with props from the route match as well as any matching elements (like 'id' for /users/:id)

<RouteProvider/>

Tracks and binds history to React. Place this in your top level provider.

<MatchedRoute/>

Renders the currently matched route with the route passed as props. Place this in the body of your application below the <RouteProvider/>

useShowLoading(timeoutMs=100): boolean

This returns true when React is transitioning in Suspense. Use this to render a loading indicator in your application.

Dependencies (4)

Dev Dependencies (3)

Package Sidebar

Install

npm i @anansi/router

Weekly Downloads

256

Version

0.9.5

License

Apache-2.0

Unpacked Size

122 kB

Total Files

41

Last publish

Collaborators

  • ntucker
  • ljharb