Friday, November 22

Getting Started with React Router v4

There are certain things we just can’t build applications without: routing is one of them. Routing is necessary when switching between components in an application. React Router is one of many options you have when it comes to implementing routing in React applications. React Router continues to receive constant updates and is now at v4.x which is readily compatible with React v16.

In this tutorial, we’ll go through the vital concepts needed to get started with React Router 4. We’ll set up our project with create-react-app which provides a quick way to get a react environment up and running.

Preparing our application

#React App Setup

At this point we’ll need to have create-react-app installed. If you haven’t done this yet, run this command to install it globally:

npm install -g create-react-app

Now that we have create-react-app installed. The next step is to initialize our application. To do this run

create-react-app demo-router

In this case, demo-router is the name of our application, create-react -app will take care of setting up our base folder structure which will look something like this

|---public
|------favicon.ico
|------index.html
|------manifest.json
|---src
|------app.css
|------app.js
|------app.test.js
|------index.css
|------index.js #
|------logo.svg
|------registerServiceWorker.js
|---.gitignore
|---package.json
|---README.md
|---yarn.lock

We’ll be using Semantic UI React which is a great styling framework with really good documentation that I recommend checking out. This will help us make use of a number of pre-built components to speed up our development process.

We’ll also be using yarn as our default package manager. Yarn is a great alternative to npm as it locks down dependency versions — a feature that was added to recent versions of npm. Yarn is also the default package manager for create-react-app. If you don’t have yarn yet, you can find the installation instructions here

Naturally, the first step would be to install the semantic-ui-react npm package. To do so run:

yarn add semantic-ui-react

Great! Now we can import components provided by the team at Semantic UI and customize them to our liking. But first we need to add the Semantic UI CSS to our project. So paste the following in your index.html file within the public folder.

// index.html
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.12/semantic.min.css"></link>

For this project you will need the image assets located here

Now let’s create a components folder under the src directory under which we’ll have the various components we’ll be using as samples, cd into the components folder and run the following command

touch  myFirstComponent.jsx

Now add the following code into myFirstComponent.jsx

// myFirstComponent.jsx
import React from 'react'
import { Card, Icon } from 'semantic-ui-react'

const description = [
  'Anakin is a Jedi string with the force.',
  'Qui Gon Jin brought him before the council believing him to be the chosen one.',
].join(' ')

const CardExtraContent = () => (
  <Card>
    <Card.Content header='About Anakin' />
    <Card.Content description={description} />
    <Card.Content extra>
      <Icon name='user' />
      4 Friends
    </Card.Content>
  </Card>
)

export default CardExtraContent

This is a sample card that we’ll use as our first view. Now let’s create another sample component and call it articleItem.jsx.

// articleItem.jsx
import React from 'react'
import { Button, Icon, Item, Label, Image } from 'semantic-ui-react'

const paragraph = <Image src='/assets/images/wireframe/short-paragraph.png' />

const ItemDivided = () => (
  <Item.Group divided>
    <Item>
      <Item.Image src='/assets/images/wireframe/image.png' />

      <Item.Content>
        <Item.Header as='a'>The Force Awakens</Item.Header>
        <Item.Meta>
          <span className='cinema'>IMAX</span>
        </Item.Meta>
        <Item.Description>{paragraph}</Item.Description>
        <Item.Extra>
          <Label>IMAX</Label>
          <Label icon='globe' content='Additional Languages' />
        </Item.Extra>
      </Item.Content>
    </Item>

    <Item>
      <Item.Image src='/assets/images/wireframe/image.png' />

      <Item.Content>
        <Item.Header as='a'>Rogue One</Item.Header>
        <Item.Meta>
          <span className='cinema'>Fox Cinema</span>
        </Item.Meta>
        <Item.Description>{paragraph}</Item.Description>
        <Item.Extra>
          <Button primary floated='right'>
            Buy tickets
            <Icon name='right chevron' />
          </Button>
          <Label>Limited</Label>
        </Item.Extra>
      </Item.Content>
    </Item>

    <Item>
      <Item.Image src='/assets/images/wireframe/image.png' />

      <Item.Content>
        <Item.Header as='a'>The Last Jedi</Item.Header>
        <Item.Meta>
          <span className='cinema'>IFC</span>
        </Item.Meta>
        <Item.Description>{paragraph}</Item.Description>
        <Item.Extra>
          <Button primary floated='right'>
            Buy tickets
            <Icon name='right chevron' />
          </Button>
        </Item.Extra>
      </Item.Content>
    </Item>
  </Item.Group>
)

export default ItemDivided

Awesome! Now we have our first two components to switch between. To do this though, we will use a navbar component. Create a navBar.jsx file and add the following code to it.

// navBar.jsx
import React, { Component } from 'react'
import { Menu } from 'semantic-ui-react'
import logo from '../logo.svg'

class NavBar extends Component {
  state = {}

  handleItemClick = (e, { name }) => this.setState({ activeItem: name })

  render() {
    const { activeItem } = this.state

    return (
      <Menu stackable>
        <Menu.Item>
          <img src={logo} />
        </Menu.Item>

        <Menu.Item
          name='feed'
          active={activeItem === 'feed'}
          onClick={this.handleItemClick}
          href='/feed'
        >
          Feed
        </Menu.Item>

        <Menu.Item
          name='card'
          active={activeItem === 'card'}
          onClick={this.handleItemClick}
          href='/card'
        >
          Card
        </Menu.Item>
      </Menu>
    )
  }
}

export default NavBar

Now let’s add the navbar we’ve just created to our app. We can do this by editing App.js. We’ll need to remove the code added by create-react-app and replace it with our nav bar component. Once done, the file should look like this:

// app.js
import React, { Component } from 'react';
import './App.css';
import NavBar from './components//navBar';

class App extends Component {
  render() {
    return (
      <div >
          <NavBar />
          <div>
            {this.props.children}
          </div>
      </div>
    );
  }
}

export default App;

You will notice we also added {this.props.children}. This is where the child components we declare in our router will be rendered. Now look at your app in the browser, it should look something like this:
Nav Bar Component

Setting Up Our Router

Now that we are all set up, let’s get to the main reason we are here, setting up our router. Naturally, the first step will be to install dependencies.

yarn add react-router react-router-dom

Now let’s create our a routes.js file where we’ll declare our routes:

cd src/
touch routes.jsx

And next we declare our routes in routes.jsx

// routes.jsx
import React from 'react'
import { Route, Switch } from 'react-router-dom'
import App from './App'
import Feed from './components/feedComponent';
import Card from './components/myFirstComponent';

const Routes = () => (
    <App>
        <Switch>
            <Route exact path="/feed" component={Feed} />
            <Route exact path="/card" component={Card} />
        </Switch>
    </App> )

export default Routes

We have wrapped our routes inside the App component here, this means it will be the parent component and all components will be rendered within it as child components. The switch statement above is one of a number of route declaration options provided by React Router v4. It is easy to use and great when it comes to authenticated routes, which we will cover later in this tutorial.

Now that we have already declared our routes we’ll need to edit the app entry point to make use of our newly declared routes. We’ll need to make some changes to index.js and have it render our routes component wrapped inside react-router-dom’s BrowserRouter component. BrowserRouter enables our app to make use of the HTML 5 history API to sync our UI with the URL.

Making these changes, the file should now look like this:

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import registerServiceWorker from './registerServiceWorker';
import Routes from './routes';
import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(
    <BrowserRouter >
        <Routes />
    </BrowserRouter >
    , document.getElementById('root'));
registerServiceWorker();

Now fire up the app and click on any of the links on the NavBar. It redirects to the specific components. Pretty cool, right?

Authenticated Routes

Most applications will feature protected routes that require the user to login to gain access. You could do this in a number of ways. I personally like Auth0 which provides awesome social login via Google, Github, Windows, you can check it out here. Follow this tutorial to set up Auth0 for your React App. Note that if you had previously worked on integrating GitHub with an Auth0 application you may have to use a different port from the previous application to allow differentiation of the two applications.

Once Auth0 is set up we’ll need to define a method in our routes.js file to handle authentication. After thar we’ll use the ternary operator(?) to choose which components are rendered for authenticated users. With these changes, your routes.jsx file should now look like this:

import React from 'react';
import { Route, Switch, Redirect } from 'react-router-dom'
import App from './App';
import Feed from './components/feedComponent';
import Card from './components/myFirstComponent';
import Auth from './utils/AuthService';
import Authed from './components/Authed';
import Callback from './components/Callback';
import history from './utils/History';

const auth = new Auth();

const handleAuthentication = (nextState, replace) => {
  if (/access_token|id_token|error/.test(nextState.location.hash)) {
    auth.handleAuthentication();
  }
}

const Routes = () => (
    <App>
        <Switch>
            <Route exact path="/feed" component={Feed} />
            <Route exact path="/card" component={Card} />
            <Route exact path="/authed" render={(props) => (!auth.isAuthenticated() ? ( <Redirect to="/feed"/> ): (<Authed auth={auth} {...props} />))} />
            <Route exact path="/callback"  render={(props) => {
            handleAuthentication(props);
            return <Callback {...props} /> 
            }}/>
        </Switch>
    </App> )

export default Routes

The link to the authed component should be added to the NavBar as well. Now try clicking on authed on the NavBar. You should see something like this:

Restricted Component

URL Parameters

You may sometimes need to pass and access parameters in your applications and this is pretty simple with React Router 4. Say for instance we wanted to have a route that takes our name as a parameter and says hello to us. We can add it to our routes file as below

<Route exact path="/hello/:name" component={Hello} />

In this case :name is a dynamic variable whose value is accessible to our component via props by as this.props.match.params.name. Let’s use this in a component:

// Hello.jsx
import React, { Component } from 'react'
import { Card } from 'semantic-ui-react'

class Hello extends Component {
    render(){
        const name = this.props.match.params.name;
        return(
            <Card
                header={`Hello ${name}`}
                description={`This route uses your name in the URL params. You are ${name}`}
            />
        )
    }
}

export default Hello

In your browser try entering the URL we added to the routes file replacing the name parameter with your name, hit enter and you should see your name on the card rendered on your browser which in my case looked like this:
Route Params Example

Conclusion

Congratulations! You are now equipped with the basics you need to get started with React Router v4, with what we’ve covered you should be able to set up routing in your React applications easily. You may also be interested in checking out this tutuorial which covers React Router 3.


Source: Scotch.io

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x