Simplifying Nested Routes in React Router
Tags: react, webdev, beginners, javascript
Published: 2024-05-24 09:12:00

## Introduction
React Router v6 introduces a powerful and flexible way to manage routing in React applications. With features like nested routes, index routes, relative paths, NavLink, and Outlet components, it offers a seamless navigation experience. In this guide, we'll walk through setting up a React application with nested routes and explore these features in detail.

### Key Concepts
**1. Index Route**
An index route is the default child route that renders when the parent route is matched but no other child routes are matched. It's typically used to display a default view or landing page for a section of your application.

In **`App.js`**, the index prop on a **<Route>** inside dashboard makes Profile the default component for /dashboard.

```react
<Route path="dashboard" element={<Dashboard />}>
  <Route index element={<Profile />} />
  <Route path="settings" element={<Settings />} />
</Route>
```
**2. Nested Routes**
In React, nested routes simply refer to a routing structure in which routes are included in other routes, resulting in a tree of routes. This concept is critical for developing applications with complex navigational structures because it allows you to create menus with multiple levels or sub-pages that can relate to the main page.

In simple terms, **UI sharing** between pages is easier.

```react
<Routes>
        <Route path="/" element={<Layout />}>
          <Route index element={<Home />} />
          <Route path="dashboard" element={<Dashboard />}>
            <Route index element={<Profile />} />
            <Route path="settings" element={<Settings />} />
          </Route>
        </Route>
</Routes>

```
**3. NavLink**
NavLink is a React component which allows us to navigate within a React application. It is similar to the Link component, but with additional features that make it ideal for creating navigational links with **active styling**.

When you use the **end** prop, NavLink is only considered active if the route matches the URL exactly. Without the end prop, NavLink can be active on any sub-path.

```react
<NavLink to="/" end style={({ isActive }) => ({ color: isActive ? 'red' : 'black' })}>
  Home
</NavLink>
<NavLink to="dashboard" style={({ isActive }) => ({ color: isActive ? 'red' : 'black' })}>
  Dashboard
</NavLink>
```
**4. Outlet and Context**
**Outlet** is a placeholder component for nested routes. It serves as a method for rendering child components or routes within a parent component. 

**Context** can be passed down the route tree.This enables you to share data and functionality between route components.

The Outlet component renders the matched nested route. Outlet context is provided to share data between parent and child routes.

```react
<Outlet context={{ user }} />
```
**5. useOutletContext**

The library provides a hook called **useContextOutlet** that lets you access the closest **<Outlet>** component in your component hierarchy. When you need to access the outlet's context, this can be helpful.

```react
import { useOutletContext } from 'react-router-dom';

const Profile = () => {
  const { user } = useOutletContext();
../
<p>Name: {user}</p>
../
```
**6. Relative Paths**
In Dashboard, Link to="" navigates to the Profile component which is a index route and Link to="settings" navigates to the Settings component.

```react
<Link to="">Profile</Link>
<Link to="settings">Settings</Link>
```

### Getting Started
First, create a new React application using create-react-app and install react-router-dom.

```bash
npx create-react-app react-router-example
cd react-router-example
npm install react-router-dom
```
### Setting Up Routes
In **`App.js`**, we'll define our routes using the Routes and Route components. We'll also create nested routes for the dashboard.

```react
import React from 'react';
import { Routes, Route, BrowserRouter } from 'react-router-dom';
import Layout from './components/Layout';
import Home from './components/Home';
import Dashboard from './components/Dashboard';
import Profile from './components/Profile';
import Settings from './components/Settings';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Layout />}>
          <Route index element={<Home />} />
          <Route path="dashboard" element={<Dashboard />}>
            <Route index element={<Profile />} />
            <Route path="settings" element={<Settings />} />
          </Route>
        </Route>
      </Routes>
    </BrowserRouter>
    
  );
}

export default App;
```
#### Creating the Layout Component
The Layout component includes navigation links and an Outlet for nested routes.

```react
import React from 'react';
import { NavLink, Outlet } from 'react-router-dom';

const Layout = () => {
  return (
    <div>
      <nav>
        <ul>
          <li>
            <NavLink to="/" end style={({ isActive }) => ({ color: isActive ? 'red' : 'black' })}>
              Home
            </NavLink>
          </li>
          <li>
            <NavLink to="dashboard" style={({ isActive }) => ({ color: isActive ? 'red' : 'black' })}>
              Dashboard
            </NavLink>
          </li>
        </ul>
      </nav>
      <hr />
      <Outlet />
    </div>
  );
};

export default Layout;
```
#### Home Component
The Home component is a simple functional component.

```react
import React from 'react';

const Home = () => {
  return (
    <div>
      <h2>Home</h2>
      <p>Welcome to the home page!</p>
    </div>
  );
};

export default Home;

```
#### Dashboard Component with Nested Routes
The Dashboard component includes links for its **nested routes** and an **Outlet** for rendering them.

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

const Dashboard = () => {
  const user = { name: 'John Doe', role: 'Admin' }; // Example user data

  return (
    <div>
      <h2>Dashboard</h2>
      <nav>
        <ul>
          <li>
            <Link to="">Profile</Link>
          </li>
          <li>
            <Link to="settings">Settings</Link>
          </li>
        </ul>
      </nav>
      <hr />
      <Outlet context={{ user }} />
    </div>
  );
};

export default Dashboard;

```
#### Profile Component
The Profile component retrieves context data using **useOutletContext**.

```react
import React from 'react';
import { useOutletContext } from 'react-router-dom';

const Profile = () => {
  const { user } = useOutletContext();

  return (
    <div>
      <h3>Profile</h3>
      <p>Name: {user.name}</p>
      <p>Role: {user.role}</p>
    </div>
  );
};

export default Profile;

```
#### Settings Component
The Settings component also uses **useOutletContext** to access user data.

```react
import React from 'react';
import { useOutletContext } from 'react-router-dom';

const Settings = () => {
  const { user } = useOutletContext();

  return (
    <div>
      <h3>Settings</h3>
      <p>Adjust your settings here, {user.name}.</p>
    </div>
  );
};

export default Settings;

```
## Conclusion
React Router v6 provides an effective approach in React applications for complex routing systems. Through usage of nested routes, index routes, NavLink, and Outlet, this allows creation of the organized and changeable navigation system. By following this guide step by step, developers will be able to lay out a foundation for making advanced React applications.