In this article, let's take a look at the nested routes to feature with react-router, so far we have seen how react-router helps us navigate across pages in our application.

But what you should know is that react-router also helps to switch between a portion of the view inside the page. If that is a little confusing, let me explain with a simple scenario.

React router v6 nested routes


In our current application, consider a third navigation link called products when we click on the link we are navigated to slash products which render a new products page. now this is something we are already familiar with



But now within this products page, we have something special, we have a search bar to search for a product, but below the search bar, we have two more links featured and new.


If you click on featured the URL updates to slash products slash featured the search bar and the links will stay in place and only the UI below the link will change and render a list of featured products.

if you click on new the URL changes to slash products slash new the search bar and links will stay in place but the list of featured products are switched with the UI that renders a list of new products.

As you can see only a portion of the UI changes based on the route, to achieve this we make use of nested routes.

If you want to know about ReactJs, please go through the below link

What is react and why react why react is declarative

let's understand, how it works one step at a time

Step:-1 

We are going to configure a new route to the products page and add a link in the navbar so within the components folder create a new file called products.js, within the file create a component that renders a search input, so input type is equal to search and placeholder is equal to search products.


Products.js

import React from 'react'

export const Products = () => {
return (
<div>
<input type='search' placeholder='Search products' />
</div>
)
}

In app.js add a new route, so route path is going to be equal to products and element is going to be equal to the products component we have just defined, make sure to import the component at the top

App.js


import { Component } from 'react'
import { Routes, Route } from 'react-router-dom'
import { OrderSummary } from './components/OrderSummary';
import { PageNotFound } from './components/PageNotFound';
import { Products } from './components/Products';

import Welcome from './components/Welcome'

function App() {
return (
<Routes>
<Route path="/" element={Welcome} />
<Route path="contact" element={Component} />
<Route path="order-summary" element={OrderSummary} />
<Route path="products" element={<Products />} />
<Route path="*" element={<PageNotFound />} />
</Routes>
);
}

export default App;

In navbar.js add a third link to slash products, so copy the about link paste it, and change slash about to slash products and about text to products if we now head to the browser we should have the products link and products page working as expected 


Step 2 

we're going to add another set of navigation links within the products component, so I'm going to wrap it with fragments and add a nav tag for the links, we need the link component from React router, so at the top import link component from react-router-dom and within the nav tag the first link is going to be for the featured products and the second link is going to be for new products, on the link component, we specify the to prop this is going to be featured and the second one is going to be new, make sure you don't include the forward-slash for the nested route.

Products.js

import React from 'react'
import { Link } from 'react-router-dom'

export const Products = () => {
return (
<>
<div>
<input type='search' placeholder='Search products' />
</div>
<nav>
<Link to='featured'>Featured</Link>
<Link to='new'>New</Link>
</nav>
</>
)
}

if we save this file and take a look at the browser you should see both the links.

Step 3

We're going to create two new components that need to be rendered for future products and new products and also configure the new routes.

So, in the components folder create two new files FeatureProducts.js and NewProducts.js, within the files create a simple component that reads the corresponding text list of featured products and list of new products, the actual content doesn't matter as long as it's different.

FeaturedProducts.js

import React from 'react'

export const FeaturedProducts = () => {
return (
<div>
List of Featured Products
</div>
)
}


NewProducts.js

import React from 'react'

export const NewProducts = () => {
return (
<div>
List of New Products
</div>
)
}

Now, what we need to do is configure new routes for these two components, more specifically configure nested routes.

Now both the components have to be nested within the products route for nesting, we're going to change route from a self-closing tag to one that has a closing tag, so opening tag and closing route tag, within the opening and closing tags, we're going to define two new routes so route path is equal to featured an element is going to be equal to FeaturedProducts similarly route path is equal to new and element is equal to NewProducts, make sure to import both the components at the top.

App.js


import { Component } from 'react'
import { Routes, Route } from 'react-router-dom'
import { FeaturedProducts } from './components/FeaturedProducts';
import { NewProducts } from './components/NewProducts';
import { OrderSummary } from './components/OrderSummary';
import { PageNotFound } from './components/PageNotFound';
import { Products } from './components/Products';

import Welcome from './components/Welcome'

function App() {
return (
<Routes>
<Route path="/" element={Welcome} />
<Route path="contact" element={Component} />
<Route path="order-summary" element={OrderSummary} />
<Route path="products" element={<Products />} >
<Route path="featured" element={<FeaturedProducts />} />
<Route path="new" element={<NewProducts />} />
</Route>
<Route path="*" element={<PageNotFound />} />
</Routes>
);
}

export default App;

What is special about nested routes is that react-router automatically forms the full path to the children routes so featured is actually slash products slash featured and new is slash products slash new

We have now configured routes to render the child component within the parent component that is featured products or new products within the products component. However, the products page still doesn't know where to render the child component, for that react order provides an Outlet component.

Products.js

import React from 'react'
import { Link, Outlet } from 'react-router-dom'

export const Products = () => {
return (
<>
<div>
<input type='search' placeholder='Search products' />
</div>
<nav>
<Link to='featured'>Featured</Link>
<Link to='new'>New</Link>
</nav>
<Outlet />
</>
)
}

So import it at the top and invoke it below the nav tag and that is pretty much the code required, let's test it out in the browser click on products, and the URL changes to slash products, the products component is also rendered. now click on featured the URL changes to slash products featured and we see the list of featured products being displayed which corresponds to the text from the featured products component click on new and the URL changes to slash products slash new and the NewProducts Component is rendered.

We are able to change only a portion of the UI on the same page whenever the URL changes, this is how the nested routes feature works with react-router

Let me summarize what we have done 

We first created a products component and configured a route for the same path is products and element is the products component 

We then added a link in the navbar to navigate to the products page 

We then created two more components for featured and new products, but this time we configured the routes to these components as nested routes 

We did that by including the route component within a route component, since the parent route component path is products the child component path will automatically have the parent path as a prefix so the new routes become products slash feature and slash products slash new.

But the parent component needs to know what to do with these child components in the routes tree for that we used the outlet component from react-router, the outlet component renders the component corresponding to the matching child route from the parent list of routes

Nested components as you can see it is very powerful, one of the common use cases of doing this is to have a common layout for a feature in your application, the parent route will render the layout component if you can call it that and within the LayoutComponent use the Outlet component to render different child components.

Thank you for reading this article.  I'll see you guys in the next one.

Here is the link to know more about React routes