Skip to content

Instantly share code, notes, and snippets.

@zcaceres
Created March 28, 2017 20:50
Show Gist options
  • Save zcaceres/5ef7c06202f9a09bf05659a7f61ca6dc to your computer and use it in GitHub Desktop.
Save zcaceres/5ef7c06202f9a09bf05659a7f61ca6dc to your computer and use it in GitHub Desktop.
FSA 1702 – March 28, 2017

React Router

FSA 1702 – March 28, 2017

Simpler Single-Page Applications


The Old Way

  • Make many requests, get your files
  • Make a new request, get a new page

Views are stored on the server, served as HTML pages. Each page retrieves a new stylesheet etc.

The Single Page Application

Let's not render a new page each time.

  1. We make a get request to start
  2. We click a link
  3. Instead of making a request and getting a full HTML page, we just get data back
  4. The front-end receives that data and slots it in properly, re-rendering the page to reflect that data
  5. The browser doesn't refresh

Instead of the server doing all the work,

We get our data with AJAX.

Multi-page feel

We want url to change (superficially) so we can use the browser history, back and forward, and create the feel of multiple pages. (Browser History API)

React Router

  • Keeps your UI in sync with the URL
  • Ties into history/url for easy navigation
  • Easily integrates nesting of components

A router is a URL and COMPONENT combined

<!-- localhost:3000/#/somepath/foo Everything after the # is ignored because the browser can't parse it!-->

<Router>
  <Route path="/somepath" component={SomeComponent}>
    <Route path="foo" component={FooComponent} /> <!-- When appended to somepath, we get a route -->
  </Route>
  <Route path="/otherpath" component={OtherComponent} />
</Router>

Back-end routes and front-end routes are very different! Don't confuse them.

Let's Code a Route!

Link replaces a href as a way navigate without going to a new page.

// Front-end
import React from 'react';
import ReactDOM from 'react-dom';
import {Route, Router, hashHistory, browserHistory, Link } from 'react-router';

class App extends React.Component {
  render() {
    return (
      <div>
      <h1> Here is the main app </h1>
      <ul>
        <li><Link to="/puppies">puppies</Link></li>
        <li><Link to="/kittens">kittens</Link></li>
      </ul>
        {this.props.children} // Will render the children from this parent route
      </div>

    )
  }
}

// Our backend has routes to return JSON for our puppies

class Puppies extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      puppies: []
    }
  }

  componentDidMount () {
    axios.get('/api/puppies')
    .then(res => res.data)
    .then(data => {
      this.setState({
        puppies: data
      })
    })
  }
  render() {
    return (
      <div> Here are the puppies </div>
      {this.state.pupies.map(puppy => {
        return {
          <div key={puppy.id}>
            <Link to={`/puppies/${puppy.id}`}>{puppy.name}</Link>
          </div>
        }
      })}
      {this.props.children && cloneElement(this.props.children, {
        puppies: this.state.puppies
      })} // If there are props children, we want to clone this.props.children, and then pass down the props object we want. cloneElement returns a copy of our element with props added!
    )
  }
}

class Puppy extends React.Component {
  constructor(props) {
    super(props),
    this.state = {
      selectedPuppy = {}
    }
  }

  componentDidMount () {
    axios.get(`api/puppies/${this.props.params.id}`)
    .then(res => res.data)
    .then(data => {
      this.setState({selectedPuppy: data})
    })
  }

  componentWillReceiveProps (nextProps) {
    axios.get(`api/puppies/${this.nextProps.params.id}`)
    .then(res => res.data)
    .then(data => {
      this.setState({selectedPuppy: data})
    })
  }

  render() {
    const {name, image} = this.state.selectedPuppy;
    return (
      <div>
        <h1>{name}</h1>
        <img src={image} alt=""/>
      </div>
    );
  }


}

ReactDOM.render (
  <Router history={hashHistory}>
    <Route path='/' component={App}>
      <Route path='/puppies' component={Puppies}>
        <Route path='/puppies/:id' component={Puppy}></Route>
      </Route>
    </Route>
  </Router>
  document.getElementById('app');
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment