Introduction to React Router v4

Linked Projects:

Calreact
 
Lesson code - https://github.com/learnetto/calreact/tree/m7-react-router

In this module we’re going to learn how to use React Router, so that we can turn our calendar app into a fully functional single page app. We want to be able to view individual appointments on their own page, edit them and delete them.module we’re going to learn how to use React Router, so that we can turn our calendar app into a fully functional single page app. We want to be able to view individual appointments on their own page, edit them and delete them.

So we’ll need some client side routes which we will add using the React Router library.

When a user visits a new route, we won’t need to reload the entire page, we’ll just fetch and display the relevant data via AJAX calls.

By the way, in the video, I pronounce it as router but a lot of people say rowter. I think that’s the American pronunciation, but I live in England so I say router. I hope you don’t mind!

React Router version 4 came out recently, and it’s much simplified and improved compared to version 3. I do recommend looking at the official documentation for React Router. It’s quite nice.

So now to get started we need to add the react-router-dom package to our app.

Let’s cd into the client directory and then run:

npm install react-router-dom --save

Now we’re going to create a new component called AppRouter.

Let’s make a new file called AppRouter.jsx.

We need to import React and then BrowserRouter and Route from react-router-dom:

import React from react.
import {BrowserRouter as Router, Route} from react-router-dom

BrowserRouter is one of the routers available in this library. It comes with support for the HTML5 history API. We'll call it Router instead of BrowserRouter in our code and throughout this class.

Then let’s define a stateless functional component:

export default (props => {
  return (
    <Router>
    </Router>
  )
}

So this Router itself is a React component and we’ll nest all our app routes inside it.

Let’s define a root for the homepage.

<Router>
  <Route path=“/“>
</Router>

Route is a component and path is one of its props.

Another prop we need to pass is a component to specify what we want to render at this route.

<Router>
  <Route path=“/“ component={Appointments} />
</Router>

To be able to use the Appointments comp, we need to add it to the imports at the top of the file

import Appointments from './Appointments';

We need to change our index view file, index.html.haml. Let’s replace Appointments with AppRouter.

= react_component('AppRouter', params: {appointments: @appointments})

The other thing we need to change is the startup registration file, registration.jsx. Again, replace Appointments with AppRouter.

import AppRouter from '../components/AppRouter';

Now we can try the this in the browser. Something is not quite working yet.

[screenshot 3:02]

We haven’t passed a value for the appointments prop. If you remember, we defined it as a required prop in the Appointments component. So there’s PropTypes coming to our rescue again.

How do we pass a prop to a component on a route? Until version 3 of React Router, we could do it just like any other component props:

<Router>
  <Route path=“/“ component={Appointments} appointments={props.appointments} />
</Router>

However, that has changed in version 4.

Let me demonstrate something. Let’s go into the Appointments component and just add console.log(props):

constructor (props , railsContext) {
  super(props)
  console.log(props);
  this.state = {
...

Now I’ll reload the page.

[screenshot: 3:43]

And you’ll see the props that are being passed to this component, but our appointments prop is missing. All we have is history, location, and match. We didn’t pass these. These props are coming from React Router.

So in React Router, every route has these 3 props: history, location, and match. History gives you the browser history, location, as the name suggestions, gives you the current location, and match gives you any additional URL parametres like an ID.

The way to pass a prop in React Router 4 is to use the render prop instead of the component prop.

Render accepts a function as a value. So we'll use an arrow function and directly use the Appointments component:

<Router>
  <Route path=“/“ render={props => (
    <Appointments {...routeProps} />
  )} />
</Router>

Note that these routeProps are different from the props.

Let’s pass the routeProps using a spread operator. The spread operator (...) is a shorthand for expanding all the props and passing them.

For example, if routeProps equals:

routeProps = {a: 1, b: 2}

then 

...routeProps

is the same as passing a and b separately as props.

Next, we can pass the appointments prop as props.appointments:

<Router>
  <Route path=“/“ render={props => (
    <Appointments {...routeProps} appointments={props.appointments} />
  )} />
</Router>

If you then refresh the page, you will see that our data load correctly. So we’ve just set up ReactRouter and got our existing route, i.e. the homepage, working with it.

Liked this tutorial? Get more like this in your inbox