learn-react-router

React Router is a routing library for React. It makes it easy to synchronize the components of your application with your URL, as well as providing easy nesting of components.

Getting started

This guide will assume some basic knowledge of React. If you have none, start with the docs: http://facebook.github.io/react/docs/getting-started.html

You can use React Router by installing it via npm and using a module bundler such as browserify or webpack, or by using the CDN.

In this guide we'll be using the npm module and webpack. If you have no experience using a module bundler, check out this guide to get started.

To install:

npm install react-router

Example

This repo contains the code for a simple restaurant menu written with React, to show how to use nested routing.
To view the page: clone the repo, run

webpack

in your terminal, and open index.html in your browser.

The most relevant file to this guide is routes.js:

var routerModule = require('react-router');
var history = require("react-router/lib/HashHistory").history;
var Router = routerModule.Router;
var Route = routerModule.Route;
var App = require('./components/app.js');

<Router history={history}>
  <Route component={App}>
    ...
  </Route>
</Router>

To start, we declare the Router component, and pass it the React Router HashHistory module. The history module is what manages the link between the UI and the URL. In your own app, you will probably want to use the BrowserHistory module which is designed for use in modern browsers. It requires configuration in your server though (see: http://rackt.github.io/react-router/tags/v1.0.0-beta3.html#BrowserHistory), so in this simple example, we will use the fallback HashHistory.

The next step is to declare the main component of our app. In our case it is the component we have exported from app.js:

var React  = require('react');
var Navbar = require('./nav.js');

var App = React.createClass({
  render: function() {
    return (
      <div className="app">
        <Navbar />
        {this.props.children}
      </div>
    );
  }
});

module.exports = App;

Here, when we define the App component, we nest inside it our Navbar component, and {this.props.children}.

The Navbar is where we provide the links to our other components, using React Router's Link Component:

var React  = require('react');
var routerModule = require('react-router');
var Link = routerModule.Link;

var Navbar = React.createClass({
  render: function() {
    return (
      <nav>
        <ul>
          <Link to="/home"><li>Home</li></Link>
          <Link to="/breakfast"><li>Breakfast</li></Link>
          <Link to="/lunch"><li>Lunch</li></Link>
          <Link to="/dinner"><li>Dinner</li></Link>
        </ul>
      </nav>
    );
  }
});

module.exports = Navbar;

The Link component will render an anchor tag with the relevant href.

{this.props.children}, when using React Router, will refer to whichever component is currently active. That is, which component's path matches the current URL. We'll see exactly what this means by looking further into routes.js:

var Redirect = routerModule.Redirect;

<Route component={App}>
  <Redirect from='/' to='/home' />
  <Route path='home' component={Home} />
  <Route path='breakfast' component={Breakfast}>
    ...
  </Route>
  <Route path='lunch' component={Lunch}>
    ...
  </Route>
  <Route path='dinner' component={Dinner}>
    ...
  </Route>
</Route>

So from this, we can see that if the URL ends with "/breakfast", {this.props.children} will be the Breakfast component, if the URL ends with "/lunch", it will be the Lunch component, and so on...

We can also see that we have a Redirect component. This redirects the path to "/home" when the URL is just "/", meaning the Home component is the default.

Another interesting thing to note is that the Link that leads to the active component automatically has a className of "active" added to it, so you can easily style it differently if you wish:

.active li{
  color: steelblue;
}

Next we'll look at some nested routes. Back to routes.js:

<Route path='breakfast' component={Breakfast}>
  <Route path='drinks' component={BreakfastDrinks} />
  <Route path='food' component={BreakfastFood} />
</Route>

Now the router will automatically resolve the urls, so if you go to '/breakfast/drinks' the BreakfastDrinks component will become active.