Categories
JavaScript React

Defining Nested Routes with React Router

Spread the love

React is a library for creating front end views. It has a big ecosystem of libraries that work with it. Also, we can use it to enhance existing apps.

To build single-page apps, we have to have some way to map URLs to the React component to display.

In this article, we’ll look at how to define nested routes with React Router.

Nested Routes

To define nested routes, first, we define a grandchild route to display the content of the nested routes. We can use the useParams hook to get any route parameters.

Then we can define nested routes by defining a child component to hold our nested routes.

In the child component, we get the url and path properties from the useRouteMatch hook.

Then we use the url variable to prefix the path in the to prop of the Link s. In the Route components, we prefix the path prop with the path property returned from useRouteMatch .

Then we create a parent component that holds the child route that we defined above.

For example, we can define them as follows:

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

function Topic() {  
  let { topicId } = useParams(); return (  
    <div>  
      <h3>{topicId}</h3>  
    </div>  
  );  
}

function Topics() {  
  let { path, url } = useRouteMatch(); return (  
    <div>  
      <h2>Topics</h2>  
      <ul>  
        <li>  
          <Link to={`${url}/foo`}>Foo</Link>  
        </li>  
        <li>  
          <Link to={`${url}/bar`}>Bar</Link>  
        </li>  
        <li>  
          <Link to={`${url}/baz`}>Baz</Link>  
        </li>  
      </ul> <Switch>  
        <Route exact path={path}>  
          <h3>Please select a topic.</h3>  
        </Route>  
        <Route path={`${path}/:topicId`}>  
          <Topic />  
        </Route>  
      </Switch>  
    </div>  
  );  
}

function App() {  
  return (  
    <Router>  
      <div>  
        <ul>  
          <li>  
            <Link to="/">Home</Link>  
          </li>  
          <li>  
            <Link to="/topics">Topics</Link>  
          </li>  
        </ul> <hr /> <Switch>  
          <Route exact path="/">  
            <p>Home</p>  
          </Route>  
          <Route path="/topics">  
            <Topics />  
          </Route>  
        </Switch>  
      </div>  
    </Router>  
  );  
}const rootElement = document.getElementById("root");  
ReactDOM.render(<App />, rootElement);

On the top of the code above, we have the Topics component to display the content of the nested route. We get the id URL parameter with useParams .

The Route that renders Topic has the path of /topics/:topicId . :topicId indicates a placeholder that we can get from useParams .

Then we have the Topics component, which is the parent of the Topic component. It has the child routes as defined in the following code:

<Switch>  
    <Route exact path={path}>  
        <h3>Please select a topic.</h3>  
    </Route>  
    <Route path={`${path}/:topicId`}>  
        <Topic />  
    </Route>  
</Switch>

In the Route we nest Topic in it so we display whatever’s returned there.

The path is set to path={`${path}/:topicId`} so that we call useRouteMatch to prefix the path with what we’ll define in App . That means path will be set to /topics as we’ll do later.

We also have the Link component’s to props prefixed with the url so that they’ll go to the right URL when we click on the links.

Then in App , we have:

<Switch>  
    <Route exact path="/">  
        <p>Home</p>  
    </Route>  
    <Route path="/topics">  
        <Topics />  
    </Route>  
</Switch>

to set the top-level routes. As we mentioned before, we’ll set the top-level route to topics as we did in the second Route component.

In the Link components, we set the relative paths to go to when we click on them.

Then we get something like the following when we click on the links:

Conclusion

To define nested routes, we have to nest Route objects within each other.

The cleanest way to do this is to split each level of nesting into their own components.

We can use the useRouteMatch hook to return the path, and url . The path is for prefix the path prop of Route s, and url is for prefixing the to prop of Links of nested routes.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

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