React Router: Add the Power of Navigation

React Router: Add the Power of Navigation

Let’s make some navigational React components with React Router

Let’s make some navigational React components with React Router

In this article we’ll cover:

  • What React Router is
  • Setting up your first routes
  • The importance of using ‘Exact’
  • 404 Component and Switch
  • Links
  • Navigation
  • Rendering several components at once
  • Nested routes

I’ll walk you through React Router as if you were coding alongside me, so open up your code editor if you’ve got one!

What is React Router?

React Router is a library that lets you delineate your routes on the front-end, so a user sees one component of your choice on localhost:3000/homepage, another on localhost:3000/faq, and others on /links, /contact, etc. You can make a React app already, but clicking around now is the name of the game.

Setting up your first routes

Let’s write three components in a components.js file in src that we’ll later put on different ‘pages’ or routes. (Your compiler may whine that you don’t need to import React, but we will need it soon.)

import React from "react"

 const Homepage = () => {
  return "Welcome to my website about my pets."
}

const Dog = () => {
  return "My dog Thundric is great. I couldn’t decide between Thunder or Electric. Don’t call him Rick."
}

const Cat = () => {
  return "I love my cat Smalls. He sure is hefty."
}

export { Homepage, Dog, Cat }

Soon we’ll be able to access each component like so:

localhost:3000/ localhost:3000/dog localhost:3000/cat

Next we make a Routes page in our src directory. Let’s name it routes.js.

Make a component called Routes and npm install ‘react-router-dom’.

import React from "react"

const Routes = () => {
  return <div></div>
}

export default Routes

Now let’s write our routes.

First we import Route:

import { Route } from "react-router-dom"

Then on each line of the Route tag, we choose a pathname, followed by the component.

<Route path="/path-name-goes-here" component={ComponentName} />

Your routes page should look something like this. We have a very important attribute called ‘exact’ in our Homepage route; we’ll go over it right after we’re set up.

import React from "react"
import { Route } from "react-router-dom"
import { Homepage, Dog, Cat } from "./components"

const Routes = () => {
&nbsp; return (
&nbsp; &nbsp; <div>
&nbsp; &nbsp; &nbsp; <Route exact path="/" component={Homepage} />
&nbsp; &nbsp; &nbsp; <Route path="/dog" component={Dog} />
&nbsp; &nbsp; &nbsp; <Route path="/cat" component={Cat} />
&nbsp; &nbsp; </div>
&nbsp; )
}

export default Routes

Now let’s go to index.js and edit our ReactDOM.render() function so it accesses our Routes instead of create-react-app’s default App component. Don’t forget to import your Routes page.

Import { Router } from ‘react-router-dom’ and have Router tags encase our Routes page.

Finally, in order for us to track our navigation, import createHistory from ‘history/createBrowserHistory’, assign createHistory() to a variable named history, and have history be the ‘history’ attribute of Router.

Your routes file should look like this:

import React from "react"
import ReactDOM from "react-dom"
import "./index.css"
import Routes from "./routes"
import { Router } from "react-router-dom"
import createHistory from 'history/createBrowserHistory'
import * as serviceWorker from "./serviceWorker"
const&nbsp;history&nbsp;=&nbsp;createHistory()

ReactDOM.render(
  <Router history={history}>
    <Routes />
  </Router>,
  document.getElementById("root")
)

serviceWorker.unregister()

Run npm start to see where you’re at.

You should be able to access each of your components at their respective paths by manually typing them in (we will write links with Link soon):

localhost:3000/ localhost:3000/dog localhost:3000/cat

The importance of using ‘exact’

Let’s go over the incredible importance of the ‘exact’ attribute found in our homepage Route:

<Route exact path="/" component={Homepage} />

To give you an idea of how critical the attribute is, try deleting “exact,” save, and try visiting each of the three paths in your browser. What happens?

You should end up seeing something like this:

All is well here, but if we go to /cat…

Wait a minute… the homepage and the cat component are showing up?

Make it stop!!!

Much like an if-else statement made up of only ifs, the Router is going down your list of routes and seeing what matches. In case of ‘/dog’, it includes ‘/’ so it renders the Homepage component and the Dog component. For ‘/cat’, the same thing happens, except with the Cat component.

‘exact’ fixes this problem, as it ensures we are only rendering a component if it matches exactly.

‘Not Found’ 404 Component

Following the logic of how Route decides which routes to display, can you guess how we can make a “page not found” component render any time an unrecognized pathname is accessed?

We add this to our components:

const NotFound = () => {
&nbsp; return "Page not found."
}
…
export { … NotFound }

And a final Route in routes.js, with no path attribute:

<Route component={NotFound} />

Keep it at the bottom, so it’s only reached when none of our other pathnames match the user’s request.

But this isn’t enough! The most important part is importing the Switch route from ‘react-router-dom.’ Switch enables us to only render one component at a time. If we don’t use Switch, our 404 route always renders at the bottom of our pages.

If your routes.js page is ready and looks something like this…

import React from "react"
import { Route, Switch } from "react-router-dom"
import { Homepage, Dog, Cat, NotFound } from "./components"

const Routes = () => {
&nbsp; return (
&nbsp; &nbsp; <div>
&nbsp; &nbsp; &nbsp; <Switch>
&nbsp; &nbsp; &nbsp; &nbsp; <Route exact path="/" component={Homepage} />
&nbsp; &nbsp; &nbsp; &nbsp; <Route path="/dog" component={Dog} />
&nbsp; &nbsp; &nbsp; &nbsp; <Route path="/cat" component={Cat} />
&nbsp; &nbsp; &nbsp; &nbsp; <Route component={NotFound} />
&nbsp; &nbsp; &nbsp; </Switch>
&nbsp; &nbsp; </div>
&nbsp; )
}

export default Routes

…try inputting a nonsense pathname to see your 404 page appear.

Note that Switch is not a substitute for exact. In fact, if you delete ‘exact’ from your Homepage route now, your /dog and /cat routes won’t show up when you visit them! We simply stay on the first route whose pathname most immediately matches the user’s input — for /dog and /cat, the buck stops at ‘/’.

Links in React Router

Now, finally, let’s write links in our components.js file.

In components.js or in your Homepage component file, Import { Link } from ‘react-router-dom’, and write a link with this format to link to dog and cat:

<Link to="/pathname">Click here</Link>

Your Homepage might now look like this:

const Homepage = () => {
&nbsp; return (
&nbsp; &nbsp;&nbsp;<div>
&nbsp; &nbsp; &nbsp; <p>Welcome to my website about my pets.</p>
&nbsp; &nbsp; &nbsp; <ul>
&nbsp; &nbsp; &nbsp; &nbsp; <li>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Link to="/dog">My Dog</Link>
&nbsp; &nbsp; &nbsp; &nbsp; </li>
&nbsp; &nbsp; &nbsp; &nbsp; <li>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Link to="/cat">My Cat</Link>
&nbsp; &nbsp; &nbsp; &nbsp; </li>
&nbsp; &nbsp; &nbsp; </ul>
&nbsp; &nbsp; </div>
&nbsp; )
}


Navigation

We don’t need to depend on the browser’s navigation buttons to return to the homepage; we can make our own back and forward buttons for our Dog and Cat components.

You can imagine the history object as an array containing indexes that indicate where we are in terms of ‘back’ and ‘forward.’ Someone who has been clicking around without hitting ‘back’ is at the end of the array, but when they hit back once, they are now at the second-to-last index. Pretty straightforward, right?

A button that takes us back a step, regardless of where we came from, looks like this:

const Dog = props => {
  return (
    <div>
      <p>
        My dog Thundric is great. I couldn’t decide between Thunder or Electric. Don’t call him Rick.
      </p>
      <p>
        <button onClick={() => props.history.goBack()}>Back</button>
      </p>
    </div>
  )
}

A forward button would look like this:

<button onClick={() => props.history.goForward()}>Forward</button>

And one that goes N steps forward or backward like this:

<button onClick={() => props.history.go(-2)}>Back two pages</button>

We can even add a home button that pushes Homepage into our history ‘array’, and takes us there:

<button onClick={() => props.history.push("/")}>Home</button>

Rendering several components at once (Nav bar style)

You may not want your entire webpage to transform with every click, so don’t overlook this way of writing your routes. Try it yourself:

const Routes = () => {
  return (
    <div>
      <p>Hi there! This text stays put, and the other components rotate below.</p>
      <Switch>
        <Route exact path="/" component={Homepage} />
        <Route path="/dog" component={Dog} />
        <Route path="/cat" component={Cat} />
        <Route component={NotFound} />
      </Switch>
    </div>
  )
}


Finding space outside of Switch routes is ideal for a navigation bar; it stays in one place as the user clicks through routed components.

const Routes = () => {
 return (
   <div>
     <Link to="/">Homepage</Link> {/*...etc*/}
     <Switch>
       <Route exact path="/" component={Homepage} />
       <Route path="/dog" component={Dog} />
       <Route path="/cat" component={Cat} />
       <Route component={NotFound} />
     </Switch>
   </div>
 )
}

Nested Routes

Topic change: you put your pets’ website aside, and made a new one about your marbles collection.

If you would like to feature each of your 1,000 marbles on your website individually, it makes sense to create just one component to reuse for each.

But how can React Router help us out here?

This would be a nightmare:

const Routes = () => {
  return (
    <Switch>
      <Route path="/marble/1" component={Marble} />
      <Route path="/marble/2" component={Marble} />
      <Route path="/marble/3" component={Marble} />
      ...
    </Switch>
  )
}

Instead we can use the params feature:

const Routes = () => {
  return (
    <Switch>
      <Route path="/marble/:id" component={Marble} />
      <Route component={NotFound} />
    </Switch>
  )
}

Amazing! So, how does the component know which marble to display?

Let’s look at the ready-to-go Marble component.

const Marble = props => {
 return <div>This is Marble number {props.match.params.id}!</div>
}

‘props.match.params’ accesses the ‘params’ (the bit after the colon) we set in our Routes. Depending on what pathname is accessed by the user, we will go to a Marble component tailored to the ID in the URL.

So if a user clicks a link that takes them here:

localhost:3000**/marble/241**

The component will render: “This is Marble number 241!”

Below is a more fleshed-out Marble component, which not only displays the ID to the user, but pulls the correct marble from the database using the ID given in the URL. That’s a much more dynamic use of params; the user probably cares about a lot more than just the ID!

class Marble extends Component {
  constructor() {
    super()
    this.state= {
      color: "",
      millimeters: 0
    }
  }

  async componentDidMount() {
    try {
      const res = await axios.get(`/marble/${this.props.match.params.id}`)
      const uniqueMarble = res.data
      this.setState({
        color: uniqueMarble.color,
        millimeters: uniqueMarble.millimeters
      })
    } catch (err) {
      console.error(err)
    }
  }

  render() {
    return <div> This is Marble number {this.props.match.params.id}!
                 It's the color {this.state.color} and only {this.state.millimeters} millimeters small.</div>
  }
}

In summary

Here is what we covered:

  • What React Router is
  • Setting up your first routes
  • The importance of using ‘Exact’
  • 404 Component and Switch
  • Links
  • Navigation
  • Rendering several components at once
  • Nested routes

And that is React Router! Share this article to show your network how much you know.

Related Posts

Learn React.js for Beginners

React Hooks Tutorial for Beginners: Getting Started With React Hooks

Learn React - React Crash Course 2019 - React Tutorial with Examples

Modern React with Redux

The Complete React Web Developer Course (2nd Edition)

Node with React: Fullstack Web Development

Beginner Full Stack Web Development: HTML, CSS, React & Node

React JS and Redux - Mastering Web Apps

React 16 - The Complete Guide (incl. React Router 4 & Redux)

MERN Stack Front To Back: Full Stack React, Redux & Node.js

Why ReactJS is better for Web Application Development?

Why ReactJS is better for Web Application Development?

Web Application Development is the point of contact for a business in today's digital era. It is important to choose the right platform for Web Application Development to build a high end Web

Web Application Development is essential for a business in today’s digital era. Finding the right platform for Web Application Development is important for building an effective Web Application that can enhance the overall customer engagement. Here’s what makes ReactJS a better option for building your next Web Application.

Mobile App Development Company India | Ecommerce Web Development Company India

Mobile App Development Company India | Ecommerce Web Development Company India

Best Mobile App Development Company India, WebClues Global is one of the leading web and mobile app development company. Our team offers complete IT solutions including Cross-Platform App Development, CMS & E-Commerce, and UI/UX Design.

We are custom eCommerce Development Company working with all types of industry verticals and providing them end-to-end solutions for their eCommerce store development.

Know more about Top E-Commerce Web Development Company

Hire PHP Developer and Web Developer for your Online Business

Hire PHP Developer and Web Developer for your Online Business

PHP is widely used open-source scripting language it helps in making dynamically easy your websites and web application. Mobiweb Technology is your best technical partner and offering you solution for any kind of website and application...

PHP is widely used open-source scripting language it helps in making dynamically easy your websites and web application. Mobiweb Technology is your best technical partner and offering you solution for any kind of website and application development. To hire PHP developer and web developer at affordable prices contact Mobiweb Technology via [email protected]