/ react.js

React Roadway

I was working on documentation for another project, and got to the point where I needed to add a router to my app. Of course, the my first instinct was to install React Router. It's the 'go to' router for more React projects, I've used it before, so why not?

Looking at the documentation, I honestly got a little lost. Mostly because I hate lots of reading in documentation. I like code and pictures. Also, I had only very briefly looked at version 4 of React Router, which is very different from previous versions. And to be honest, I didn't really like it. It seemed over complicated. All I really wanted to do, was click on something, and have it render a specific component. Sounds simple. So I decided to give it a go on my own.

React Roadway

I started making my own router, and so far, IT WORKS! It does exactly what I need it to. I made mine work a little differently than React Router. It has Router and Link components, but it also uses higher-order components for creating the Routers, Routes, and Links from any other component.

Example

import React from 'react';
import { render } from 'react-dom';
import { createRouter, createRoute, Link } from 'react-roadway';

const Home = () => (
  <div>Home</div>
);

const HomeRoute = createRoute(Home);

const About = () => (
  <div>About</div>
);

const AboutRoute = createRoute(About);

const App = () => (
  <div>
    <ul>
      <li><Link href="/">Home</Link></li>
      <li><Link href="/about">About</Link></li>
    </ul>
    <HomeRoute match="/" />
    <AboutRoute match="/about" />
  </div>
);

const Router = createRouter(App);

render(<Router />, document.getElementById('root'));

What's going on?

Using a higher-order component (HOC), for createRouter, means that whatever component is passed in gets history and location properties added to it. These can also be passed down to it's children. The Router component, is created using this HOC. The Router source is this:

import React from 'react';
import createRouter from './createRouter';

const Router = ({ history, location, ...props }) => (
  <div {...props} />
);

export default createRouter(Router);

Basically, all I've done is take a div and pass it to createRouter. The result is a new component that has history and location. The history is managed using the history package. This is created by the same group that made React Router. I will likely look at making my own history at somepoint in the future, but for now this package is perfect.

The HOC, createRoute gets history and location from context and adds that to the wrapped component, along with params and any search criteria (query string). The query string is not parsed (yet). I haven't made a Route component like I did with Router, but that will likely happen in the very near future.

The Link component, like Router uses a HOC to add an onClick function. All the onClick does, is prevent the default click event, and pushes the new location to the history. By default, it also calls window.scrollTo(0,0) to return to the top of the page. This can be disabled by adding scroll={{ false }} to Link.

Overall, I'm pretty happy with what I got working here. I'm going to update the documentation and GitHub Pages, then publish it to npm in the next day or two. Check it out now on GitHub, NPM, or the Documentation.