Skip to content

Blazing Fast and Lightweight router for reactjs based on state first

Notifications You must be signed in to change notification settings

Cervantes007/rift-router

Repository files navigation

rift-router GitHub license code style: prettier Build Status codecov

Blazing Fast and Lightweight router for React Based on state first..

Features

  • Lightweight 1.8kb (min/gzip) - 5kb (min)
  • No Dependencies
  • Blazing Fast update app state first and then Browser Sync.
  • Useful route information in params, search, path and active router properties.
  • Typescript first class, but works fine with javascript too.
  • Nesting Route.
  • Lazy loading for route component.
  • Hooks onEnter and onLeave.
  • Redirect.
  • Route Guard.
  • Automatic Browser Sync
  • Isomorphic.

Installation

npm i -s rift-router

Usage

import React, {lazy} from 'react';
import ReactDOM from 'react-dom';
import { IRiftRoute, RiftProvider, RiftGate, RiftLink } from 'rift-router';

const Home = () => <div>'Home Component'</div>;
const About = () => <div>'About Component'</div>;

const routes: IRiftRoute[] = [
  { path: '/', component: <Home /> },
  { path: '/about', component: () => <About /> },
  { path: '/users', component: lazy(() => import('./users')),
];

ReactDOM.render(
  <RiftProvider routes={routes} fallback={<div>loading...</div>}>
    <RiftLink to="/">Home</RiftLink>
    <RiftLink to="/about">About</RiftLink>
    <RiftGate /> {/* render the component for current route */}
  </RiftProvider>,
  document.getElementById('root')
);

Check basic usage in a sandbox:

Edit RiftRouter Basic

and that's it, try it.

Routes object options.

Using Hooks:

function isUserLogged() {...}
const routes = [
    {
        path: '/users',
        component: <UserList />,
        onLeave: () => '...Do some logic when current route will change',
        onEnter: () => {
            if(!isUserLogged()) {
                return '/login';
            }
        }
    }
]

onEnter run just before set new route, therefore it can be used as route Guard, if onEnter return an string value, the router will redirect to this value.

Handle route not match

const routes = [
  // Default route (*) redirect to '/'
  { path: '*', onEnter: () => '/' },
  // Default route keep browser url and show Home component
  { path: '*', component: <Home /> },
  // Default route show Not Found Page component
  { path: '*', component: <NotFound404 /> },
];

Nesting routes

const routes: IRiftRoute[] = [
  {
    path: '/admin',
    component: () => 'admin',
    children: [
      {
        path: '/users',
        component: () => 'users',
      },
      {
        path: '/users/:id?',
        component: () => 'users editor',
      },
    ],
  },
];

note: For each nesting you must place a <RiftGate/> component to display current nesting component.

Building your routes with many files and lazy loading components.

// somewhere in the users module/folder
export const usersRoutes = [
  {
    path: '',
    component: React.lazy(import('./UserList')),
  },
  {
    path: '/:id',
    component: React.lazy(import('./UserDetails')),
  },
];
// building your routes with others routers files.
const routes: IRiftRoute[] = [
  {
    path: '/users',
    children: usersRoutes,
  },
];

Lazy loading your component will reduce the first load time, therefore your page will be show faster, then other component will be load in demand.

Caveat: React.lazy and Suspense are not yet available for server-side rendering. If you want to do code-splitting in a server rendered app check <a href="https://reactjs.org/docs/code-splitting.html#reactlazy">here</a>

router instance API:

  • path (show current path - router.path -> '/users')
  • params (for path = /users/:id - current route = 'users/5' -> router.params = {id: 5})
  • search (for route = /users?from=home -> router.search = {from: "home"})
  • to function receive a string parameter for navigate to (router.to('/users'))

How to get router object

Option 1: In your component use the router from RiftContext using useRouter hook.

const Home = () => {
  const router = useRouter();
  const toAbout = () => router.to('/about');
  return (
    <div>
      <div>Home Component</div>
      <button onClick={toAbout}>About us</button>
    </div>
  );
};

Option 2: In your route inject the router instance as a component prop, same for onEnter and onLeave hooks

const routes: IRiftRoute[] = [
  { path: '/', component: <Home />, onEnter: router => {...} },
  { path: '/about', component: router => <About router={router} /> },
];

How it Work.

  1. Pass your routes to RiftProvider and it will create a router instance and share it through React.Context to be use deep in the component tree with the useRouter hook. RiftProvider also accept a fallback prop where you can provide a component to will be shown by all yours RiftGate while lazy components finish to load.

  2. RiftGate works as a gateway to show the correct component for the active route. If you have nesting routes you must use the same number of RiftGate to render the nested components in the active route. Also accept a fallback prop where you can provide a component to show while lazy components finish to load, this will override the fallback of the RiftProvider.

TODO:

Add Documentation for

  • Code Splitting.
  • Server Side Rendering Example.

About

Blazing Fast and Lightweight router for reactjs based on state first

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published