Site navigation using React Router 3

Wed, 5 Oct 2016

These code snippets demonstrate how to create navigation that automatically updates as routes are added.

First, add the react-router-active-component plugin:

yarn add react-router-active-component

or

npm install --save react-router-active-component

This allows an “active” class to be added to the navigation anchor’s parent li element, a feature the built in Link component lacks.

index.js:

import React from 'react'
import ReactDOM from 'react-dom'

// Pages
import App from './containers/App' // wrapper
import Start from './containers/Start'
import AnotherPage from './containers/AnotherPage'

// History without ?_k=
import { Route, Router, useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'
const appHistory = useRouterHistory(createHashHistory)({ queryKey: false })

ReactDOM.render(
  <Router history={appHistory}>
    <Route component={App}>
      <Route path="/" component={Start} name="Start" />
      <Route path="/another-page" component={AnotherPage} name="Another PAge" />
    </Route>
  </Router>,
  document.getElementById('root')
)

containers/App.js:

import React, { Component } from 'react'
import Header from './../components/Header'

class App extends Component {
  render() {
    return (
      <div className="App">
        <Header routes={this.props.routes} />

        <div className="container">{this.props.children}</div>
      </div>
    )
  }
}

export default App

components/Header.js:

import React, { Component } from 'react'
import { Link } from 'react-router'

// For wrapping Link
import activeComponent from 'react-router-active-component'
let NavItem = activeComponent('li', { linkClassName: 'nav-link' })

class Header extends Component {
  render() {
    return (
      <div className="Header">
        <nav className="navbar navbar-fixed-top navbar-light bg-faded">
          <div className="container-fluid">
            <div className="navbar-header">
              <Link to="/" className="navbar-brand">
                Create-React-App Playground
              </Link>
            </div>
            {/* Main Nav */}
            <ul className="nav navbar-nav pull-xs-right">
              {this.props.routes[0].childRoutes.map(route => (
                <NavItem
                  key={route.path}
                  to={route.path}
                  className="nav-item Header__navItem"
                >
                  {route.name}
                </NavItem>
              ))}
            </ul>
          </div>
        </nav>
      </div>
    )
  }
}

export default Header

If you would like to comment on this post, feel free to tweet me @will_stone_