React Router Navigation

Understanding the Problem

We need to implement navigation in a React application using React Router. This involves:

Devising a Plan

  1. Set up a layout route structure to contain shared navigation
  2. Implement Link components for basic navigation
  3. Add NavLink components with active styling
  4. Create protected routes with Navigate component
  5. Add programmatic navigation with useNavigate hook

Basic Solution Implementation

File Structure:

src/
  ├── App.jsx
  ├── components/
  │   ├── Layout.jsx
  │   ├── Home.jsx
  │   ├── Stocks.jsx
  │   └── Movies.jsx
  └── index.css

Layout Component (Layout.jsx)

// Layout.jsx
import { Outlet, NavLink } from 'react-router-dom';

function Layout() {
  return (
    <div className="app">
      <h1>App Component</h1>
      <nav className="comp nav">
        <ul>
          <li>
            <NavLink 
              to="/"
              className={({isActive}) => isActive ? 'purple' : ''}
              style={({isActive}) => ({fontWeight: isActive ? 'bold' : 'normal'})}
            >
              Home
            </NavLink>
          </li>
          <li>
            <NavLink 
              to="/stocks"
              className={({isActive}) => isActive ? 'purple' : ''}
              style={({isActive}) => ({fontWeight: isActive ? 'bold' : 'normal'})}
            >
              Stocks
            </NavLink>
          </li>
          <li>
            <NavLink 
              to="/movies"
              className={({isActive}) => isActive ? 'purple' : ''}
              style={({isActive}) => ({fontWeight: isActive ? 'bold' : 'normal'})}
            >
              Movies
            </NavLink>
          </li>
        </ul>
      </nav>
      <main>
        <Outlet />
      </main>
    </div>
  );
}

Protected Route Example (Stocks.jsx)

// Stocks.jsx
import { Navigate, useNavigate } from 'react-router-dom';

function Stocks() {
  const loggedIn = false; // In real apps, this would come from auth state
  const navigate = useNavigate();

  // Redirect if not logged in
  if (!loggedIn) {
    return <Navigate to="/not-logged-in" replace />;
  }

  const handleClick = () => {
    window.alert('Sending info to the DB!');
    navigate('/');
  };

  return (
    <div>
      <h1>Stocks Component</h1>
      <button onClick={handleClick}>Home</button>
    </div>
  );
}

Router Setup (App.jsx)

// App.jsx
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import Layout from './components/Layout';
import Home from './components/Home';
import Stocks from './components/Stocks';
import Movies from './components/Movies';

const router = createBrowserRouter([
  {
    element: <Layout />,
    children: [
      {
        path: '/',
        element: <Home />
      },
      {
        path: 'stocks',
        element: <Stocks />
      },
      {
        path: 'movies',
        element: <Movies />
      },
      {
        path: 'not-logged-in',
        element: <h1>You Must Be Logged In To Enter.</h1>
      },
      {
        path: '*',
        element: <h1>Page Not Found</h1>
      }
    ]
  }
]);

Real World Applications

This pattern is commonly used in:

Common Pitfalls and Solutions

Advanced Concepts

Practice Exercises

  1. Add a dropdown menu in the navigation bar
  2. Create a breadcrumb navigation component
  3. Implement a "Back to Previous Page" button
  4. Add loading states during navigation