Day 1, Segment 3, Part 2

In notebook:
FrontEndMasters React Intro 2
Created at:
2016-12-22
Updated:
2016-12-23
Tags:
Webpack libraries React JavaScript

React Router v4

branch v2-7

React Router has just been rewritten. He's using the alpha version of React Router v4. But the concepts are universal. Check out the workshops page to see if anything has changed. 

React Router is great library but its API has changed many times. Three times in two years. They said it's the last time.

React Router 4 is a complete rewrite. It got so much better that it's worth it. Also this is the simplest one of the 4. 

Create landing page:
  // **** Landing.js  ****

import React from 'react'

const Landing = React.createClass({
  render () {
    return (
      <div className='landing'>
        <h1>svideo</h1>
        <input type='text' placeholder='Search' />
        <a>or Browse All</a>
      </div>
    )
  }
})

export default Landing
Update clientapp.js
  // ****   clientapp.js    ****

import React from 'react'
import { render } from 'react-dom'
// 1. ++++ import from router 
import { HashRouter, Match } from 'react-router'
// and Landing
import Landing from './Landing'
import Search from './Search'
import '../public/normalize.css'
import '../public/style.css'

const App = React.createClass({
  render () {
    return (
      // the root of this component
      // is the Hashrouter
      <HashRouter>
        <div className='app'>
        // add Match
          <Match exactly pattern='/' component={Landing} />
          <Match pattern='/search' component={Search} />
        </div>
      </HashRouter>
    )
  }
})

render(<App />, document.getElementById('app'))

Hashrouter

Higher-order components in React
A component that does not show anything to the user. It encapsulates behaviour. 

Hashrouter and Match are higher order components. 
Hashrouter is typically a root level component. You would put your navigation bar (visible on every page) here as well. 

Then Match component. When url matches the pattern display this component. 
Meaning of exactly
​<Match exactly pattern='/' component={Landing} />

If it's not there, it will match everything to the left, so parent routes as well. Will match /about and /about/me as well (if exactly is not there). 

Hashrouter

http://localhost:8080/#

The # at the address. This is ugly, but easier for the server – you don't need to serve all these routes (that come after the #). 
My note: quite easy to do with NodeJS or even surge.sh.

The other, nicer option is browserrouter that avoids the #. Also NodeJS can consume browserrouter routes. He will show how to do universal rendering.

Commenting in JSX

<HashRouter>
{/* comment like this  */}        
<div className='app'>

HTML comments don't work at all. 
In general, Brian doesn't comment his code that much. (I think he talks specifically about his HTML code)

Do a second route for the search page

In above code snippet:, this handles the search route :
<Match pattern='/search' component={Search} />
Create search.js :
  // ****   Search.js   ****

import React from 'react'

const Search = React.createClass({
  render () {
    return (
      <h1>Search page!!</h1>
    )
  }
})

export default Search
Now we have  http://localhost:8080/#/search

(note the /#/ in the address)

Browserrouter

In Webpack config:
Branch v2-8
  ...
    filename: 'bundle.js'
  },
  devServer: {
    publicPath: '/public/',
    // if the file is not found on the server
    // it's handeld by the client
    // reroute 404 to the home page
    historyApiFallback: true
  },
And the update the ClientApp.js 
  // ****   ClientApp.js    ****

import React from 'react'
import { render } from 'react-dom'
// 1. ++-- 
// import { HashRouter, Match } from 'react-router'
import { BrowserRouter, Match } from 'react-router'
import Landing from './Landing'
import Search from './Search'
import '../public/normalize.css'
import '../public/style.css'

const App = React.createClass({
  render () {
    return (
      // 2. ++---
      <BrowserRouter>
      // <HashRouter>
        <div className='app'>
          <Match exactly pattern='/' component={Landing} />
          <Match pattern='/search' component={Search} />
        </div>
      </HashRouter>
      // </BrowserRouter>
    )
  }
})

render(<App />, document.getElementById('app'))
Explains that he demoed last year, almost the same code running on VR, Arduino, etc. 

Now we have  http://localhost:8080/search

Miss component in React router

It will redirect all unmatched routes to what you define for the miss component.