DEV Community

Junko T.
Junko T.

Posted on • Updated on

Implementing client-side routing with React Router

If you decide to use React for your application, you will likely be building a Single Page Application(SPA). As your application grows, you will want your app to have multiple URLs that contain different components. This is where client-side routing comes in.

The major benefit of client-side routing is speed. Using client-side routing, the whole application is loaded on the first GET request. Because of this, it can take a while when the application first mounts, but then we don't have to wait for a round trip server call for each page change after that.

React Router is the most popular routing library for React. It allows you to create intuitive routes that are human-readable so it will be easy to manage the application structure.

I am going to walk you through how to implement client-side routing in a React application using React Router step by step.

Installation

In your application, run this:

$ npm install --save react-router-dom
Enter fullscreen mode Exit fullscreen mode

Or, if you are using yarn, run:

yarn add react-router-dom
Enter fullscreen mode Exit fullscreen mode

Implementation

Add routes

Let's first create the <Home> page and add /home routes in our application so we can go to http://localhost:3000/home to see the <Home> page.

Here is our simplest <Home> page:

// myapp/src/components/Home.js

import React from 'react'

const Home = () => {
  return (
    <>
      <h1>Home page</h1>
      <h3>Welcome to my app!</h3>
    </>
  )
}

export default Home
Enter fullscreen mode Exit fullscreen mode

Now, in App.js, let's set up a route to load the Home component:

// myapp/src/App.js

import React from 'react'
import { BrowserRouter, Route } from 'react-router-dom'
import Home from './components/Home'

const App = () => {
  return (
    <>
      <h1>My App</h1>
      <BrowserRouter>
        <Route path="/home" component={Home} />
      </BrowserRouter>
    </>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

home page
Great! The <BrowserRouter> component creates a base router and the <Route> component configures each route and specifies the component that should render.

Let's also create <AboutUs> and <Contact> pages and add /about and /contact routes as well:

// myapp/src/components/AboutUs.js

import React from 'react'

const AboutUs = () => {
  return (
    <h1>About us</h1>
  )
}

export default AboutUs
Enter fullscreen mode Exit fullscreen mode
// myapp/src/components/Contact.js

import React from 'react'

const Contact = () => {
  return (
    <h1>Contact page</h1>
  )
}

export default Contact
Enter fullscreen mode Exit fullscreen mode
// myapp/src/App.js

import React from 'react'
import { BrowserRouter, Route } from 'react-router-dom'
import Home from './components/Home'
import Contact from './components/Contact'
import AboutUs from './components/AboutUs'

const App = () => {
  return (
    <>
      <h1>My App</h1>
      <BrowserRouter>
        <Route path="/home" component={Home} />
        <Route path="/about" component={AboutUs} />
        <Route path="/contact" component={Contact} />
      </BrowserRouter>
    </>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

about us
contact

Exact path

exact path
Hmmm, this is not exactly what we want. We want to show <Contact> page only when we go to /contact. In this case, we can use the exact attribute:

// myapp/src/App.js

import React from 'react'
import { BrowserRouter, Route } from 'react-router-dom'
import Home from './components/Home'
import Contact from './components/Contact'
import AboutUs from './components/AboutUs'

const App = () => {
  return (
    <>
      <h1>My App</h1>
      <BrowserRouter>
        <Route path="/home" component={Home} />
        <Route path="/about" component={AboutUs} />
        <Route exact path="/contact" component={Contact} />
      </BrowserRouter>
    </>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

exact path
Great! Now /contact/something path doesn't render <Contact> component.

Use <Switch> to set up exclusive routes

What if you change your mind and you want to add home/about instead of /about? Sure, we can do that. But first, you need to know how <Switch> works.

<Switch> works as the switch statement in JavaScript. It checks the path, and, as soon as it finds a match, it breaks out of the block. Let me show you what would be a problem without using <Switch>:

// myapp/src/App.js

import React from 'react'
import { BrowserRouter, Route } from 'react-router-dom'
import Home from './components/Home'
import Contact from './components/Contact'
import AboutUs from './components/AboutUs'

const App = () => {
  return (
    <>
      <h1>My App</h1>
      <BrowserRouter>
        <Route path="/home" component={Home} />
        <Route path="/home/about" component={AboutUs} />
        <Route exact path="/contact" component={Contact} />
      </BrowserRouter>
    </>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

nested route
Oh no. Why do we see the <Home> component too? This happens because of the way JavaSript matches strings.

> "/home".match("/home/about")
null
Enter fullscreen mode Exit fullscreen mode

If I match /home with /home/about, it returns null. On the other hand, if I match /home/about with /home:

> "/home/about".match("/home")
[ '/home', index: 0, input: '/home/about', groups: undefined ]
Enter fullscreen mode Exit fullscreen mode

I get a truthy value. This is why /home/about renders both <Home> and <AboutUs> components. We can avoid this using <Switch> because it breaks after the first match found. Don't forget to put the most specific routes first and more general routes second since <Switch> matches from the top.

// myapp/src/App.js

import React from 'react'
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import Home from './components/Home'
import Contact from './components/Contact'
import AboutUs from './components/AboutUs'

const App = () => {
  return (
    <>
      <h1>My App</h1>
      <BrowserRouter>
        <Switch>
          <Route path="/home/about" component={AboutUs} />
          <Route path="/home" component={Home} />
          <Route exact path="/contact" component={Contact} />
        </Switch>
      </BrowserRouter>
    </>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

home about
Perfect!


In the next article, I will introduce how to set up routes with parameters using React Router.

Latest comments (0)