npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-routerjs

v0.5.2

Published

React bindings for routerjs

Downloads

7

Readme

npm version Donate

Routerjs - React

React bindings for RouterJS. These bindings simplify the usage of RouterJS in a react project

1. Installation

You need to install both RouterJS and react-routerjs.

with yarn

yarn add routerjs react-routerjs

or with npm

npm install --save routerjs react-routerjs

2. Usage

The main component provided by this library is a RouterProvider to which you need to pass your configured router. You should put this provider on a top position in your react project. To know how to define routes refer to RouterJS documentation

import { createRouter } from 'routerjs';
import { RouterProvider } from 'react-routerjs';
import App from './App'; // you react app code

const router = createRouter()
  .get('/', () => {
    // route handler
  });


ReactDOM.render(
  <RouterProvider router={router}>
    <App />
  </RouterProvider>
, document.getElementById('app'));

// Run the router after the render method 
// if you want to parse also the entrance url
router.run();

Any other component provided by this library must be a descendant of the RouterProvider.

3. Link

A Link component is provided to easily create anchors. Always remember that also normal anchors will fire router events (see documentation for this) but the advantage of using the Link component is that you can omit the basePath, if any, since it will automatically prepend it to any href. Link takes the same attributes as an anchor

<Link href="/post/14">Article on cats</Link>

If basePath is /blog

<Link href="/posts">Post list</Link>
// is equivalent to
<a href="/blog/posts">Post list</a>

NOTE: Link will always run your handlers even if bindClick is set ot false in your router engine, as explained here.

4. View

react-routerjs applies an opinionated way of showing a view depending on the route. This is done through two components:

  • a withView middleware
  • a RouteView component

Use withView to declare which View to show on a route. It accepts a function that gets the current req and context. You may use it to pass parameters to your components.

import { createRouter } from 'routerjs';
import { withView } from 'react-routerjs';
import UserList from './UserList';
import Post from './Post';

const router = createRouter()
  .get('/users', withView((req, ctx) => <UserList />)(
    async (req, context) => {
      context.users = await loadUsers();
    }
  ))
  .get('/post/:id', withView((req, ctx) => <Post id={req.params.id} />)(
    (req, context) => {
      await setPostAsVisited(req.params.id);
    }
  ))
  .run();

you can also use react.lazy and return a promise instead. This way your component will be lazy loaded only when the route is visited!

// ... as before
const Post = React.lazy(() => import('./Post'));

router
  .get('/post/:id', withView((req, ctx) => <Post id={req.params.id} />)(
    (req, context) => {
      await setPostAsVisited(req.params.id);
    }
  ))

Now the view will be shown in your application where the RouteView placeholder is placed

import { RouteView } from 'react-routerjs';

<div className="content">
  <RouteView />
</div>

RouteView component accepts a fallback props since it internally uses React Suspense.

The couple withView and RouteView takes another parameter, called target. The default target is called main but you can specify a different one. This let you build more complex applications. In this example we define another target called sidebar to choose which view to show in a sidebar

import { createRouter, compose } from 'routerjs';
import { withView } from 'react-routerjs';

import UserList from './UserList';
import UserSidebar from './UserSidebar';

const router = createRouter()
  .get('/users', compose(
    withView(<UserList />),  // this is in target "main" which is the default
    withView(<UserSidebar />, 'sidebar'), // this is in target "sidebar"
  )(
    async (req, context) => {
      context.users = await loadUsers();
    }
  ));

Later, in your application

<div className="main">
  <div className="content">
    /* This will show the UserList component */
    <RouteView target="main" /> 
  </div>
  <div className="sidebar">
    /* This will show the UserSidebar component */
    <RouteView target="sidebar" />
  </div>
</div>

You can do the same in case of error just using withErrorView

import { createRouter, compose } from 'routerjs';
import { withErrorView } from 'react-routerjs';

import View404 from './View404';

const on404 = () => {
  // ...
}

const router = createRouter()
  // ....
  .error(
    404, 
    withErrorView((error, ctx) => <View404 path={ctx.path} />)(on404)
  )

The only difference is that you have access to the error, not the request.

RouteView internally uses Suspense, if you want to remove it pass the props disableSuspense.

5. RouterContext and useRouter hook

To access current router context and router methods in your components, you can use the useRouter hook

import { useRouter } from 'react-routerjs';

const MyComponent = () => {
  const routerContext = useRouter();

  if(routerContext) {
    routerContext.router.navigate('/somewhere'); // method to navigate
    routerContext.context.path(); // access current path
    routerContext.context.currentUser; // For example, if your route populate the context with the user
  }
}

The routerContext contains the following properties:

The router instance with all the router methods.
The most useful will probably be:

  • router.navigate: a method to navigate to a desired url
  • router.buildUrl: a method to build an url considering the basePath

and the route context

  • context: the router context which contains

Refer to its documentation to know how the context works.

NOTE remember that routerContext can be null, so check it before usage

If you cannot use hooks, you can use the regular react context to access the same values.

6. Advanced

This is pretty much all you need to know to use RouterJS with React. Consider that RouterJS is thought to be framework agnostic and this is just one of the possible way to use it with React. If you find that this way is not the best for your project, or you want to implement a different coupling between React and RouterJS, you should create your own implementation: it's very fun!

To do it, study carefully how RouterJS works and remember that the router has an handy method, router.always((context) => {}), that let you attach some code and execute it for any route! Also, look at the implementation of this project to get some idea.