November 20, 2023

Nested Route in React

In the post Dynamic Route in React we have seen how you can add dynamic segments to the routes. In that kind of parent and child route scenario you can also use nested routes to create a component hierarchy and UI also looks better as you can display both parent and child components next to each other by using <Outlet /> in the parent component to render the child route's element.

Nested route in React

Nested routes or child routes in React gives you an option to place a route relative to another route which is not root route.

If you have followed example in this post React Router - Link in react-router-dom this has already been done so that the route, that points to Navigation, acts as a parent component and the other routes as nested routes.

How to create a child route in React

You place child routes in a children array within the parent route. For example, in the given route definition root route ("/") acts as a parent route for all the routes that's why all the other routes are defined as children.

Then we have a "/users" route and a dynamic route "/users/:userId", that is also done as a nested route so that the route with dynamic segment becomes a child route. That way as path we just need to give the child path segment (":userId") as it is relative to its parent.

export const router = createBrowserRouter([
    {path: "/", element: <Navigation />, errorElement: <ErrorPage />,
     children: [
        {index: true, element: <Home /> },
        {path: "users", element: <Users />,
            children: [
                {path: ":userId", element: <UserDetails/>}
            ]
        },
        {path: "about", element: <About />}
     ]
    },        
])

Note that in this route definiton, route paths are relative paths (does not begin with "/") which means paths resolve relative to the parent route. ":userId" is a child route of "users" so it builds upen the parent route meaning it resolves to "/users/:userId".

Nested Route React example

In the example we display a page with list of user names using Users Component. For the user’s name that is clicked user details are displayed using UserDetails component. Dynamic routing is used here to pass userId as route parameter. It is the same example used in Dynamic Route post but now we’ll place path with dynamic segment as a child route so that there is a component hierarchy between Users and UserDetails and we can show UserDetails data next to Users data by placing <Outlet /> in the Users (parent) component.

Route Definition

src\components\Routes\route.js

import { createBrowserRouter } from "react-router-dom";
import About from "./About";
import ErrorPage from "./ErrorPage";
import Home from "./Home";
import Navigation from "./Navigation";
import UserDetails from "./UserDetails";
import Users from "./Users";

export const router = createBrowserRouter([
    {path: "/", element: <Navigation />, errorElement: <ErrorPage />,
     children: [
        {index: true, element: <Home /> },
        {path: "users", element: <Users />,
            children: [
                {path: ":userId", element: <UserDetails/>}
            ]
        },
        {path: "about", element: <About />}
     ]
    },        
])

Providing the routes

Provide the route definition to your application using the <RouteProvider> component.

import { RouterProvider } from 'react-router-dom';
import { router } from './components/Routes/route';

function App() {
  return <RouterProvider router={router}></RouterProvider>
}

export default App;

Components

Two components that we need for user are Users and UserDetail.

src\components\Routes\Users.js

import { Link, Outlet } from "react-router-dom"

export const DUMMY_USERS = [
    {id: 1, name: "Ram", age: 23},
    {id: 2, name: "Namita", age: 25},
    {id: 3, name: "Varun", age: 32},
    {id: 4, name: "Leo", age: 28},
    {id: 5, name: "Melissa", age: 27},
]

const Users = () => {
    return(
        <>
            <div className= "row">
                <div className="col-sm-4">
                    <h2>Users</h2>
                    <ul className="list-group">

                        {DUMMY_USERS.map(user =><li className="list-group-item" key={user.id}> 
                            <Link to={user.id.toString()}>{user.name}</Link></li>
                        )}
                    </ul>
                </div>
                <div className="col-sm-4">
                    <Outlet />
                </div>
            </div>
            </>
   
    )
}

export default Users;

Some points to note here are-

  1. Bootstrap5 is used here for styling.
  2. In the code a hardcoded array holding user objects is created named DUMMY_USERS.
  3. Note how links are created for each user name while looping the user array
    <Link to={user.id.toString()}>{user.name}</Link>
    

    In each iteration of the array, id is added as the link. <Link> by default takes the path relative to route and the current route is “/users” which becomes “/users/CURRENT_ID” when the link is clicked. This path is matched by the route “/users/:userId”.

  4. Note the use of <Outlet /> in Users component to render the child route’s element.
    <div className="col-sm-4">
      <Outlet />
    </div>
    

src\components\Routes\UserDetails.js

import { useParams } from "react-router-dom"
import { DUMMY_USERS } from "./Users"

const UserDetails = () => {
    
    const params = useParams();
    // Find the passed ID in the DUMMY_USERS array
    // converting params.userId to number 
    const user = DUMMY_USERS.find(user => user.id === +params.userId)
    return (
        <>
            <h2>User Details</h2>
            <div className="row">
                <div className="col-xs-6">
                    <span>User Name: </span>{user.name}
                </div>
            </div>
            <div className="row">
                <div className="col-xs-6">
                    <span>Age: </span>{user.age}
                </div>

            </div>
        </>
    )
}

export default UserDetails;

Some points to note here are-

  1. useParams() hook is used here to get the value of the dynamic segment.
  2. User whose details are to be displayed is then searched in the array using the passed id.

Please refer this post- Setting Error Page (404 Page) in React Router to get code of other components like Navigation, ErrorPage, Home, About.

When you click on Users menu

When you click on the user name, it should show the corresponding user details next to it.

child route in react

That's all for the topic Nested Route in React. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment