React Router DOM

Example of basic route switching with React Router DOM.

by nimareq

HTML

<script src="https://unpkg.com/react@15/dist/react.min.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.min.js"></script>
<script src="https://unpkg.com/react-router-dom/umd/react-router-dom.min.js"></script>
<script src="https://unpkg.com/prop-types/prop-types.min.js"></script>
<div id="app"></div>

CSS

body {
  font-family: Arial, Helvetica, sans-serif;
}

nav:not(.show) {
  display: none
}

.navLinks {
  background: #333;
  list-style: none;
  margin: 0;
  padding: 1rem;
}

.navLinks li {
  display: inline-block;
}

.navLinks li a,
.navLinks li a:active, 
.navLinks li a:visited {
  color: #fff;
  padding: 1rem;
  text-decoration: none;
}

.navLinks li a:hover {
  text-decoration: underline;
}

Babel + JSX

const { BrowserRouter, Route, Switch, Link } = window.ReactRouterDOM;

const Home = () => <h1>The Home</h1>;
const Page = () => <h1>The Page</h1>;

const Navigation = ({isNavShown}) => {
  return (
    <nav className={isNavShown ? 'show' : ''}>
      <ul className='navLinks'>
        <li><Link to="/home">Home</Link></li>
        <li><Link to="/page">Page</Link></li>
      </ul>
    </nav>
  );
};

const Layout = ({children, showNav, isNavShown}) => {
  return (
    <div>
      <button id="showNavBtn" onClick={showNav}>show navigation</button>
      <label htmlFor="autoHide" id="autoHideContainer">
        <input type="checkbox" id="autoHide"/>hide navigation on click outside
      </label>
      <Navigation isNavShown={isNavShown}/>
      <main>{children}</main>
      <p>1. click "show navigation" and notice that routing works.</p>
      <p>
        2. After the checkbox is enabled, routing stops working.<br/>
        Desired is that the navigation hides and route changes.
       </p>
    </div>
  );
};

class App extends React.Component {
	state = {
  	isNavShown: false
  }
  
  showNav = () => {
  	console.debug('showNav')
  	this.setState({
    	isNavShown: true
    })
  }
  
  hideNav = event => {    
    // ignore clicks to checkbox
    if (autoHideContainer.contains(event.target)) return
    
    // ignore clicks to "show navigation" button
    if (showNavBtn.contains(event.target)) return
    
  	console.debug('auto hideNav =', autoHide.checked)
    
    // don't hide if autoHide is disabled
    if (autoHide.checked === false) return
    
    this.setState({
      isNavShown: false
    })
  }
  
  componentDidMount() {
    document.addEventListener('mousedown', this.hideNav)
  }
  
  render() {
    return (
      <BrowserRouter>
        <Layout showNav={this.showNav} isNavShown={this.state.isNavShown}>
          <Switch>
            <Route path='/page' component={Page} />
            <Route component={Home} />
          </Switch>
        </Layout>
     ...