Neutralize Pesky Miscreants

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

    0.6.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

    Demo

    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 'rest-hooks';
    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.

    Install

    npm i @anansi/router

    DownloadsWeekly Downloads

    214

    Version

    0.6.5

    License

    Apache-2.0

    Unpacked Size

    78.1 kB

    Total Files

    37

    Last publish

    Collaborators

    • ntucker
    • ljharb