All Projects → franciscop → React Plain Router

franciscop / React Plain Router

Licence: mit
🛣 A 2kb React router that works exactly as expected with native Javascript

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to React Plain Router

Vanilla Ui Router
Simple vanilla JavaScript router
Stars: ✭ 42 (-64.71%)
Mutual labels:  router, vanilla
tiny-editor
A tiny HTML rich text editor written in vanilla JavaScript
Stars: ✭ 58 (-51.26%)
Mutual labels:  vanilla, tiny
Gin
Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
Stars: ✭ 53,971 (+45253.78%)
Mutual labels:  router
Ipfs Mini
A super tiny module for querying IPFS that works in the browser and node.
Stars: ✭ 115 (-3.36%)
Mutual labels:  tiny
Core
UI-Router Core: Framework agnostic, State-based routing for JavaScript Single Page Apps
Stars: ✭ 112 (-5.88%)
Mutual labels:  router
Pilot
Pilot — multifunction JavaScript router.
Stars: ✭ 109 (-8.4%)
Mutual labels:  router
Netcopa
Network Configuration Parser
Stars: ✭ 112 (-5.88%)
Mutual labels:  router
Cherrytree
A flexible nested router.
Stars: ✭ 105 (-11.76%)
Mutual labels:  router
React Page Layout
Create layouts for react
Stars: ✭ 117 (-1.68%)
Mutual labels:  router
Sme Router
A lightweight router lib that implement with express route style
Stars: ✭ 112 (-5.88%)
Mutual labels:  router
Charm
A really tiny crypto library.
Stars: ✭ 116 (-2.52%)
Mutual labels:  tiny
Php Router
simple and flexible Router class for PHP. with Controllers and Middlewares support.
Stars: ✭ 111 (-6.72%)
Mutual labels:  router
Scalajs React
Facebook's React on Scala.JS
Stars: ✭ 1,524 (+1180.67%)
Mutual labels:  router
Router
🍭灵活的组件化路由框架.
Stars: ✭ 1,502 (+1162.18%)
Mutual labels:  router
Docker Openwrt
OpenWrt running in Docker
Stars: ✭ 107 (-10.08%)
Mutual labels:  router
Alien
A lightweight and fast http router from outer space
Stars: ✭ 115 (-3.36%)
Mutual labels:  router
Router.js
Router.js is a simple and powerful javascript library to handle routing
Stars: ✭ 107 (-10.08%)
Mutual labels:  router
Vanilla Hamburger
Animated hamburger menu icons for modern web apps (1.8 KB) 🍔
Stars: ✭ 110 (-7.56%)
Mutual labels:  vanilla
Rxviper
Android micro framework for developing apps based on clean VIPER architecture.
Stars: ✭ 112 (-5.88%)
Mutual labels:  router
Rabbits
A router module for Android application.
Stars: ✭ 118 (-0.84%)
Mutual labels:  router

React Plain Router npm install react-plain-router gzip size

A tiny React router that works exactly as expected with native Javascript:

// App.js
import React from 'react';
import router from 'react-plain-router';

// Wrap it and you can use normal anchor links
export default router(({ path, query, hash }) => (
  <div>
    <nav>
      <a href="/">Go Home</a>
      <a href="/about">About us</a>
    </nav>

    {path === '/' && <div>Hello world!</div>}
    {path === '/about' && <div>About me</div>}
  </div>
));

You have to wrap your app with router() and then both <a> links and window.history.pushState() will work as expected. It will trigger a re-render when any of these properties change: path, query or hash.

If you have parameters or complex routes you can combine it with my other library pagex for a cleaner syntax:

import router from 'react-plain-router';
import page from 'pagex';
export default router(() => (
  <div>
    {page('/', () => <div>Hello world!</div>)}
    {page('/users', () => <ul>...</ul>)}
    {page('/users/:id', id => <User id={id} />)}
  </div>
));

If a link has the attribute target, then this library will ignore it and let the browser handle it. This is very useful for target="_blank", so that the link is opened in a new tab as usual. But it will also work with target="_self", where the router will ignore the link and thus perform a full-refresh.

An event named navigation will be triggered on window every time there's a re-render. You can see the parts with e.detail, which is very useful for debugging:

// When loading /greetings?hello=world#nice
window.addEventListener('navigation', e => {
  console.log('NAVIGATION', e.detail);
  // {
  //   path: '/greetings',
  //   query: { hello: 'world' },
  //   hash: 'nice'
  // }
});

Internally, it works by using the bubbling events at the document level and then handling any link click. window.location becomes the source of truth instead of keeping an context or global store, which makes it more reliable to interact with native Javascript or http events.

router(cb)

This HOC function accepts a callback, which will be passed an arguments with the props from above and these 3 extra props:

  • path, pathname (String): the current url path, similar to the native pathname. Example: for /greetings it will be '/greetings'. An empty URL would be '/'.
  • query (Object | false): an object with key:values for the query in the url. Example: for /greeting?hello=world it will be { hello: 'world' }.
  • hash (String | false): the hash value without the #. Example: for /hello#there it will be 'there'.

A fully qualified url will parse as this:

// /greetings?hello=world#nice
router(({ path, query, hash, ...props }) => {
  expect(path).toBe('/greetings');
  expect(query).toEqual({ hello: 'world' });
  expect(hash).toBe('nice');
});

Example: navigation bar

We can define our navigation in a different component. <a> are native so they will work cross-components:

// Nav.js
export default () => (
  <nav>
    <a href="/">Home</a>
    <a href="/about">About</a>
    <a href="https://google.com/">Go to Google</a>
    <a href="/terms" target="_blank">Terms and Conditions</a>
  </nav>
);

Then you can toggle the different pages in the main App.js:

// App.js
import router from 'react-plain-router';
import Nav from './Nav';

export default router(({ path }) => (
  <div>
    <Nav />
    {path === '/' && <div>Homepage</div>}
    {path === '/about' && <div>About us</div>}
  </div>
));

The Google link will open Google, and the Terms and Conditions link will open a new tab. Everything works as expected, in the same way native html works.

Example: scroll to top on any navigation

Add an event listener to the navigation event:

window.addEventListener('navigation', e => {
  window.scrollTo(0, 0);
});

Example: simulating the <Link>

Just an example of how easy it is to work with react-plain-router, let's see how to simulate the component that the library react-router-dom defines with this library

// components/Link.js
export default ({ to, ...props }) => <a href={to} {...props} />;

Then to use our newly defined component, we can import it and use it:

// Home.js
import router from 'react-plain-router';
import Link from './components/Link';

export default router(() => (
  <Link to="/about">About us</Link>
));

But you can just use native links:

// Home.js
import router from 'react-plain-router';

export default router(() => (
  <a href="/about">About us</a>
));

Example: manual navigation

To trigger manual navigation you can use the native history.pushState() as explained in the amazing Mozilla Developer Network:

// src/actions/login
export default id => async dispatch => {
  const payload = await ky(`/api/users/${id}`).json();
  dispatch({ type: 'USER_DATA', payload });
  window.history.pushState({}, 'Dashboard', `/dashboard`);
};
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].