Welcome back to the React Mastery Series!

In the previous article, we explored Custom Hooks in React and learned how reusable logic helps developers build scalable and maintainable applications.

Today, we will explore one of the most important concepts in modern frontend development:

React Routing

Almost every real-world React application contains multiple screens:

  • Login
  • Dashboard
  • Profile
  • Settings
  • Reports
  • Transactions
  • Admin panels

But React applications are usually built as:

Single Page Applications (SPA)

So how do we navigate between different pages without refreshing the browser?

The answer is React Router


What is Client-Side Routing?

Traditional websites work like this:

User Clicks Link
       |
       ↓
Browser Requests New HTML Page
       |
       ↓
Server Sends Page
       |
       ↓
Browser Reloads

Enter fullscreen mode Exit fullscreen mode

Every navigation causes a full page refresh.


React Single Page Applications work differently:

User Clicks Link
       |
       ↓
React Router Intercepts Request
       |
       ↓
URL Changes
       |
       ↓
React Loads Component
       |
       ↓
No Page Refresh

Enter fullscreen mode Exit fullscreen mode

This creates a smooth application experience.


What is React Router?

React Router is a library that enables navigation between different components based on the URL.

Example:

/login
/dashboard
/profile
/settings

Enter fullscreen mode Exit fullscreen mode

Each URL maps to a React component.

Example:

/login
   |
   ↓
Login Component


/dashboard
   |
   ↓
Dashboard Component

Enter fullscreen mode Exit fullscreen mode


Installing React Router

For a React application:

npm install react-router-dom

Enter fullscreen mode Exit fullscreen mode

The package provides:

  • BrowserRouter
  • Routes
  • Route
  • Link
  • Navigate
  • useNavigate
  • useParams

Setting Up BrowserRouter

The first step is wrapping your application.

Example:

import { BrowserRouter } from "react-router-dom";

import App from "./App";

ReactDOM.createRoot(document.getElementById("root")).render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
);

Enter fullscreen mode Exit fullscreen mode

Now React can manage browser navigation.


Creating Routes

Routes define which component should display for a URL.

Example:

import { Routes, Route } from "react-router-dom";

function App() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />

      <Route path="/login" element={<Login />} />

      <Route path="/dashboard" element={<Dashboard />} />
    </Routes>
  );
}

Enter fullscreen mode Exit fullscreen mode

Now:

/login

Enter fullscreen mode Exit fullscreen mode

renders:

<Login />

Enter fullscreen mode Exit fullscreen mode


Understanding Route Components

Example:

<Route path="/profile" element={<Profile />} />;

Enter fullscreen mode Exit fullscreen mode

Contains path and element

The URL path specifies the url appeared in browser

Example:

/profile

Enter fullscreen mode Exit fullscreen mode


element

The component to render on visiting the path specified.

Example:

<Profile />

Enter fullscreen mode Exit fullscreen mode


Navigation Using Link

Traditional HTML - causes a browser refresh.

<a href="/dashboard"> Dashboard </a>

Enter fullscreen mode Exit fullscreen mode

React Router provides:

import { Link } from "react-router-dom";
<Link to="/dashboard">Dashboard</Link>

Enter fullscreen mode Exit fullscreen mode

Benefits:

  • No page refresh
  • SPA behavior
  • Better performance

Creating a Navigation Bar

Example:

function Navbar() {
  return (
    <nav>
      <Link to="/">Home</Link>

      <Link to="/dashboard">Dashboard</Link>

      <Link to="/profile">Profile</Link>
    </nav>
  );
}

Enter fullscreen mode Exit fullscreen mode

When users click:

Dashboard

Enter fullscreen mode Exit fullscreen mode

React loads:

<Dashboard />

Enter fullscreen mode Exit fullscreen mode

without refreshing.


Programmatic Navigation with useNavigate

Sometimes navigation happens after an action.

Examples:

  • Successful login
  • Logout
  • Form submission

Example:

import { useNavigate } from "react-router-dom";

function Login() {
  const navigate = useNavigate();

  function handleLogin() {
    // API success

    navigate("/dashboard");
  }

  return <button onClick={handleLogin}>Login</button>;
}

Enter fullscreen mode Exit fullscreen mode

Flow:

User Login
     |
     ↓
API Success
     |
     ↓
navigate("/dashboard")
     |
     ↓
Dashboard Page

Enter fullscreen mode Exit fullscreen mode


Route Parameters

Many applications need dynamic URLs.

Example:

/users/101

Enter fullscreen mode Exit fullscreen mode

Here:

101

Enter fullscreen mode Exit fullscreen mode

is dynamic.

React Router supports this using parameters.

Example:

<Route path="/users/:id" element={<UserDetails />} />

Enter fullscreen mode Exit fullscreen mode


Reading Route Parameters

Using:

useParams()

Enter fullscreen mode Exit fullscreen mode

Example:

import { useParams } from "react-router-dom";

function UserDetails() {
  const { id } = useParams();

  return <h2>User ID: {id}</h2>;
}

Enter fullscreen mode Exit fullscreen mode

URL:

/users/101

Enter fullscreen mode Exit fullscreen mode

Output:

User ID: 101

Enter fullscreen mode Exit fullscreen mode


Real-World Example: Banking Application

Consider:

/accounts/12345

Enter fullscreen mode Exit fullscreen mode

where:

12345

Enter fullscreen mode Exit fullscreen mode

is the account number.

Route:

<Route path="/accounts/:accountId" element={<AccountDetails />} />

Enter fullscreen mode Exit fullscreen mode

Component:

const { accountId }=useParams();

Enter fullscreen mode Exit fullscreen mode

Now the application knows which account to display.


Nested Routes

Large applications often have sections inside sections.

Example:

Dashboard

   |
   ├── Overview

   ├── Transactions

   └── Profile

Enter fullscreen mode Exit fullscreen mode

Routes:

<Route>
  <Route path="/dashboard" element={<Dashboard />} >
  <Route path="transactions" element={<Transactions />} />
  <Route path="profile" element={<Profile />} />
</Routes>

Enter fullscreen mode Exit fullscreen mode

URL:

/dashboard/transactions

Enter fullscreen mode Exit fullscreen mode

renders:

Dashboard
    +
Transactions

Enter fullscreen mode Exit fullscreen mode


Outlet Component

Nested routes use:

<Outlet />

Enter fullscreen mode Exit fullscreen mode

Example:

import { Outlet } from "react-router-dom";

function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>

      <Outlet />
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

The child route appears where Outlet exists.


Protected Routes

Enterprise applications often require authentication.

Example:

Users should access:

/dashboard

Enter fullscreen mode Exit fullscreen mode

only after login.

Without authentication:

/dashboard
       |
       ↓
Redirect
       |
       ↓
/login

Enter fullscreen mode Exit fullscreen mode


Creating ProtectedRoute

Example:

function ProtectedRoute({ children }) {
  const isAuthenticated = true;

  if (!isAuthenticated) {
    return <Navigate to="/login" />;
  }

  return children;
}

Enter fullscreen mode Exit fullscreen mode


Usage:

<Route
  path="/dashboard"

  element={
    <ProtectedRoute>
      <Dashboard />
    </ProtectedRoute>
  }
/>;

Enter fullscreen mode Exit fullscreen mode


Real-World Authentication Flow

Enterprise applications usually follow:

User Opens Application

        |
        ↓

Check Token

        |
        ↓

Token Exists?

        |
   -------------
   |           |
 Yes           No
   |            |
Dashboard     Login

Enter fullscreen mode Exit fullscreen mode

React Router handles navigation decisions.


Lazy Loading Routes

Large applications should not load every page immediately.

Example:

const Dashboard = lazy(() => import("./Dashboard") );

Enter fullscreen mode Exit fullscreen mode

Route:

<Suspense fallback="Loading...">
  <Routes>
    <Route path="/dashboard" element={<Dashboard />} />
  </Routes>
</Suspense>;

Enter fullscreen mode Exit fullscreen mode

Benefits:

  • Smaller initial bundle
  • Faster startup
  • Better performance

Route Organization in Enterprise Projects

A scalable structure:

src

├── routes
│    ├── AppRoutes.jsx
│    ├── ProtectedRoute.jsx
├── pages
│    ├── Login.jsx
│    ├── Dashboard.jsx
│    └── Profile.jsx
├── layouts
│    └── MainLayout.jsx

Enter fullscreen mode Exit fullscreen mode


Real-World Banking Application Routing

Example:

/login

/dashboard

/accounts

/accounts/:id

/transactions

/profile

/settings

Enter fullscreen mode Exit fullscreen mode

Flow:

Login
 |
 ↓
Authentication Success
 |
 ↓
Dashboard
 |
 ├── Accounts
 |
 ├── Transactions
 |
 └── Profile

Enter fullscreen mode Exit fullscreen mode

This is the architecture used in many enterprise React applications.


Common Mistakes

1. Using Anchor Tags

Avoid:

<a href="/dashboard"> Dashboard </a>

Enter fullscreen mode Exit fullscreen mode

Use:

<Link to="/dashboard"> Dashboard </Link>

Enter fullscreen mode Exit fullscreen mode


2. Forgetting BrowserRouter

Without:

<BrowserRouter>

Enter fullscreen mode Exit fullscreen mode

routing will not work.


3. Incorrect Nested Routes

Parent route must contain:

<Outlet />

Enter fullscreen mode Exit fullscreen mode

otherwise child routes won't appear.


4. Loading All Pages at Startup

Large applications should use:

  • lazy loading
  • code splitting

Best Practices

  • Keep routes centralized.
  • Use lazy loading for large applications.
  • Create reusable protected routes.
  • Use meaningful URL structures.
  • Avoid unnecessary route nesting.
  • Separate page components from reusable components.

Key Takeaways

Today, we learned:

✅ React Router enables navigation in Single Page Applications.
✅ Routes map URLs to React components.
Link provides SPA navigation without refresh.
useNavigate enables programmatic navigation.
useParams reads dynamic route values.
✅ Protected routes secure application pages.
✅ Lazy loading improves application performance.


Coming Next 🚀

In Day 20, we will explore:

Building Production-Ready React Applications – Project Structure and Architecture

We will learn:

  • Scalable folder structure
  • Component organization
  • Feature-based architecture
  • Separation of concerns
  • API service layers
  • Error handling
  • Environment configuration
  • Enterprise React project patterns

This will connect all the concepts we learned so far into a real-world production architecture.

Happy Coding! 🚀