React

React Router Nested Routes

nested routing

Let me show you how to write a nested routes in React using React Router.

In case you are unfamiliar with React Router on how to set basic routes in React, then please go through my article on React Router Example

Let’s create a simple app and start it by using the following commands.

npx create-react-app my-app
cd my-app
npm start

You should be able to see your sample app running and can browse through the same on your favorite browser by opening http://localhost:3000/

Now open your App.js file located in my-app/src folder and start writing some components in it.

We shall first write a Home component that will open when the user clicks on the Home link.

function Home() {
  return <h2>This is an awesome Home</h2>;
}

Then we would write a Contact component that will open when the user clicks on the Contact link.

function Contact() {
  return <h2>Contact me at abc@xyz.com</h2>;
}

Now let’s write a Subjects component that will open links to all the subjects that you are an expert in. Here is where your nested routing magic happens.

Here using useRouterMatch(), we get the current route of the page. Then we define sub-routes for this route as Link components specifying the to properties. Finally we define the Switch block where we bind what to show when the user clicks on specific sub-routes.

function Subjects() {
  let match = useRouteMatch();

  return (
    <div>
      <h2>Subjects</h2>

      <ul>
        <li>
          <Link to={`${match.url}/mathematics`}>Maths and Stats</Link>
        </li>
        <li>
          <Link to={`${match.url}/physics`}>
            Concepts of Physics
          </Link>
        </li>
      </ul>

      {/* The Subjects page has its own <Switch> with more routes
          that build on the /subjects URL path. You can think of the
          2nd <Route> here as an "index" page for all subjects, or
          the page that is shown when no topic is selected */}
      <Switch>
        <Route path={`${match.path}/:subjectId`}>
          <Subject />
        </Route>
        <Route path={match.path}>
          <h3>Please select a subject.</h3>
        </Route>
      </Switch>
    </div>
  );
}

Notice that we are calling a Subject component in the sub-routes. Let’s create that Subject component and read path params as well there. We are using the useParams() function to read path param subjectId that is passed in sub-routes above.

function Subject() {
  let { subjectId } = useParams();
  return <h3>Requested subject ID: {subjectId}</h3>;
}

Finally let’s define the main routing for the app to complete the application.

export default function App() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/contact">Contact</Link>
          </li>
          <li>
            <Link to="/subjects">Subjects</Link>
          </li>
        </ul>

        <Switch>
          <Route path="/contact">
            <Contact/>
          </Route>
          <Route path="/subjects">
            <Subjects />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

Putting it all together your App.js should look like this.

import React from 'react';
import logo from './logo.svg';

import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  useRouteMatch,
  useParams
} from "react-router-dom";


export default function App() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/contact">Contact</Link>
          </li>
          <li>
            <Link to="/subjects">Subjects</Link>
          </li>
        </ul>

        <Switch>
          <Route path="/contact">
            <Contact/>
          </Route>
          <Route path="/subjects">
            <Subjects />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

function Home() {
  return <h2>This is an awesome Home</h2>;
}

function Contact() {
  return <h2>Contact me at abc@xyz.com</h2>;
}

function Subjects() {
  let match = useRouteMatch();

  return (
    <div>
      <h2>Subjects</h2>

      <ul>
        <li>
          <Link to={`${match.url}/mathematics`}>Maths and Stats</Link>
        </li>
        <li>
          <Link to={`${match.url}/physics`}>
            Concepts of Physics
          </Link>
        </li>
      </ul>

      {/* The Subjects page has its own <Switch> with more routes
          that build on the /subjects URL path. You can think of the
          2nd <Route> here as an "index" page for all subjects, or
          the page that is shown when no topic is selected */}
      <Switch>
        <Route path={`${match.path}/:subjectId`}>
          <Subject />
        </Route>
        <Route path={match.path}>
          <h3>Please select a subject.</h3>
        </Route>
      </Switch>
    </div>
  );
}

function Subject() {
  let { subjectId } = useParams();
  return <h3>Requested subject ID: {subjectId}</h3>;
}

This is how you should see in the browser if you have not missed anything. Now go, make me proud, and build an awesome react app with nested routing.

How useful was this post?

Click on a star to rate it!

Average rating / 5. Vote count:

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

About anil

Hi, I'm Anil Verma. I have a passion for teaching and developing awesome front end apps. I was involved in development of post processor for Nastran(built by NASA). More recently I have been building supply chain apps at E2open.
View all posts by anil →

Leave a Reply

Your email address will not be published. Required fields are marked *