Tuesday, June 3, 2025

Using NavLink in React Router

In the post Link in React Router With Example we saw how to create a navigation menu or link one page to another using Link in React Router. In this post we'll see how we can use NavLink in React Router to create a Navigation Menu.

NavLink in React Router

With NavLink you can create active links which means highlighting the currently selected menu item. A link can be in active or pending state (pending state is available only with framework and data modes).

Accessing link state

In NavLink there are className and style props, using these props you can access isActive and isPending states and style them.

Using className

The className prop takes a function with an object as parameter that can be destructured to get isActive and isPending properties. These properties are of type Boolean. If current link is active then isActive has the value true otherwise value is false.

Function returns a css class name that should be added for styling.

<NavLink
  to="/about"
  className={({ isActive, isPending }) =>
    isPending ? "pending" : isActive ? "active" : ""
  }
>
  About
</NavLink>

As you can see in the above code, if isActive returns true then active is returned as the className. So, you can write your own CSS with active class styling.

Using style prop

The style prop takes a function with an object as parameter that can be destructured to get isActive and isPending properties. These properties are of type Boolean. If current link is active then isActive has the value true otherwise value is false.

Function returns style for the state.

<NavLink to="/about" style={({ isActive, isPending }) => ({
  color:
    isActive ? "red" :
    isPending ? "blue" : "black"
})}>
  About
</NavLink>

Navlink navigation menu example

1. CSS

This is the CSS class used for styling the links.

src\components\routes\navigation.css

#menu a:link,
#menu a:visited {
    color: gray;
}
#menu a:hover {
    color: white;
}
#menu a.active {
    color: #7FFFD4;
}

#menu a {
    text-decoration: none;
}

#menu ul {
    gap: 1rem;
}

2. Components

Components that are mapped to the routes

src\components\routes\Home.js

import { Link } from "react-router";
const Home = () => {
    return (
    <>
        <h2>This is home page</h2>
        <Link to="/about">About</Link>
    </>
    )
}
export default Home;

src\components\routes\About.js

const About = () => {
    return <h2>This is about page</h2>
}

export default About;

3. Navigation component

Menu for navigation is created as a separate file, uses Bootstrap 5 for styling.

src\components\routes\NavigationNavLink.js

import { NavLink, Outlet } from "react-router";
import "./navigation.css";
const NavigationNavLink = () => {
    const style = (({ isActive, isPending }) => 
        isPending ? "pending" : isActive ? "active" : ""
    );
    return(
        <>
            <nav id="menu" className="navbar navbar-expand-lg bg-dark navbar-dark">
                <div className="container-fluid">
                    <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarMenu" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                        <span className="navbar-toggler-icon"></span>
                    </button>

                    <div className="collapse navbar-collapse" id="navbarMenu">
                        <ul className="navbar-nav">
                            <li>
                                <NavLink className={style} to="/">
                                    Home
                                </NavLink>
                            </li>
                            <li>
                                <NavLink className={style} to="/about">
                                    About
                                </NavLink>
                            </li>
                        </ul>
                    </div>
                </div>
            </nav>
        </>
    );
}

export default NavigationNavLink;

App.js

Since <NavLink/> cannot be rendered outside <BrowserRouter/> so you should add the Navigation component wrapped with in the BrowserRouter.

import { BrowserRouter, Route, Routes } from 'react-router';
import About from './components/routes/About';
import Home from './components/routes/Home';
import NavigationNavLink from './components/routes/NavigationNavLink';
function App() {
  return (
    <>
      <BrowserRouter >
       <NavigationNavLink />
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="about" element={<About />} />
        </Routes>
      </BrowserRouter>
    </>
  );
}

export default App;

With these changes if you access the about page- http://localhost:3000/about

NavLink in React Router

Navigation menu with child routes and Outlet

In the above example we saw how to create a navigation menu with NavLink, it works fine but the recommended way to do it is to create routes as child routes of the navigation route.

App.js

That's where routing is configured.

import { BrowserRouter, Route, Routes } from 'react-router';
import About from './components/routes/About';
import Home from './components/routes/Home';
import NavigationNavLink from './components/routes/NavigationNavLink';
function App() {
  return (
    <>
      <BrowserRouter >
        <Routes>
          <Route path="/" element={<NavigationNavLink />}>
            <Route path="/" element={<Home />} />
            <Route path="about" element={<About />} />
          </Route>
        </Routes>
      </BrowserRouter>
    </>
  );
}

export default App;

As you can see Navigation component acts as a parent route and other components are specified as the child routes.

Navigation component

In the Navigation component add the Outlet so that the matching child route of a parent route is rendered at the place specified by Outlet.

src\components\routes\NavigationNavLink.js

import { NavLink, Outlet } from "react-router";
import "./navigation.css";
const NavigationNavLink = () => {
    const style = (({ isActive, isPending }) => 
        isPending ? "pending" : isActive ? "active" : ""
    );
    return(
        <>
            <nav id="menu" className="navbar navbar-expand-lg bg-dark navbar-dark">
                <div className="container-fluid">
                    <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarMenu" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                        <span className="navbar-toggler-icon"></span>
                    </button>

                    <div className="collapse navbar-collapse" id="navbarMenu">
                        <ul className="navbar-nav">
                            <li>
                                <NavLink className={style} to="/">
                                    Home
                                </NavLink>
                            </li>
                            <li>
                                <NavLink className={style} to="/about">
                                    About
                                </NavLink>
                            </li>
                        </ul>
                    </div>
                </div>
            </nav>
            <Outlet />
        </>
    );
}

export default NavigationNavLink;

That's all for this topic Using NavLink in React Router. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. React Declarative Approach
  2. React Virtual DOM
  3. React create-react-app Project Structure
  4. JavaScript Rest Parameter

You may also like-

  1. ArrayList in Java With Examples
  2. Count Number of Times Each Character Appears in a String Java Program
  3. Java Stream API Interview Questions And Answers
  4. What is Client Side Routing in Angular

No comments:

Post a Comment