🚦 Routing Architecture: The Illusion of Pagination
In 1999, a website was a collection of literal .html files (about.html, contact.html). When you clicked a link, the browser threw away the current page, stared at a white screen for 3 seconds, and downloaded the next .html file from the server. This is a Multi-Page Application (MPA).
React builds Single-Page Applications (SPAs). Wait, if it's a single page, how do we have URLs like /dashboard and /settings?
We fake it. A router intercepts the URL change, stops the browser from refreshing, and dynamically mounts/unmounts components instantly to simulate navigating a website.
1️⃣ React Router Version 6 (The Industry Standard)
react-router-dom is the de facto standard routing library for pure React applications.
npm install react-router-dom
The Primary Architecture
An SPA requires three core components to construct the illusion of pages.
BrowserRouter: The God-component. You wrap your entire<App />in this, granting it control over the browser's URL bar history.Routes: A mathematical switchboard. It looks at the current URL and decides which Component to show on screen.Route: A single rule mapping a URL path to a specific Component.
Basic Setup
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
{/* The Navbar sits OUTSIDE the Routes. It will persist statically on all pages! */}
<Navbar />
{/* The Switchboard */}
<Routes>
{/* If the URL is exactly "/", load the HomePage component */}
<Route path="/" element={<HomePage />} />
{/* If the URL is exactly "/about", swap in the About component */}
<Route path="/about" element={<AboutPage />} />
{/* Fallback (404 Error Page) for any unknown route */}
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
);
}
2️⃣ Avoiding Full Page Reloads (The <Link> Component)
If you use a standard HTML <a href="/about"> tag, the browser will ignore React entirely, execute a hard refresh, and destroy your entire JavaScript state data (logging out your user).
You must exclusively use React Router's <Link> component. It silently updates the URL bar and commands React to swap the components instantly, without a network reload.
import { Link } from 'react-router-dom';
function Navbar() {
return (
<nav>
{/* ❌ ILLEGAL: Triggers hard refresh */}
<a href="/login">Login</a>
{/* ✅ LEGAL: Instant, zero-refresh SPA navigation */}
<Link to="/login">Login</Link>
</nav>
);
}
3️⃣ Dynamic Parameters (The useParams Hook)
If you build an e-commerce store with 10,000 products, you cannot manually write 10,000 individual <Route> components.
Instead, you inject a Parameter Variable directly into the URL path.
Step 1: Define the Variable Route
We use a colon : to declare a wildcard variable in the math.
// This one Route handles `/products/1`, `/products/999`, `/products/apple-watch`
<Route path="/products/:productId" element={<ProductDetails />} />
Step 2: Extract the Variable Inside the Component
The <ProductDetails> component looks at the URL bar, snatches the exact ID, and uses it to fetch data.
import { useParams } from 'react-router-dom';
import { useEffect, useState } from 'react';
function ProductDetails() {
// Hooks into the URL path and extracts '{ productId: "999" }'
const { productId } = useParams();
useEffect(() => {
// We use that specific ID to hit the backend API!
fetch(`/api/database/items/${productId}`);
}, [productId]);
return <h1>Displaying Details for Item #{productId}</h1>;
}
4️⃣ Programmatic Navigation (useNavigate)
Link components are great for visible buttons in a navbar. But what if you need to redirect the user automatically via JavaScript?
For example: A user types in their password, clicks submit, the API verifies it's correct, and then you want to kick them out of the /login page and force them into the /dashboard.
You achieve this using the useNavigate hook.
import { useNavigate } from 'react-router-dom';
function LoginForm() {
// 1. Initialize the navigation function
const navigate = useNavigate();
const handleLogin = async (event) => {
event.preventDefault();
const success = await attemptAPILogin();
if (success) {
// 2. Programmatically teleport the user instantly
navigate('/dashboard');
// Pro Tip: Force them out using { replace: true } so they cannot
// click the browser's "Back" arrow to return to the empty login page!
// navigate('/dashboard', { replace: true });
}
};
return <button onClick={handleLogin}>Log In</button>;
}
5️⃣ Advanced Architecture: Nested Routes & Layouts
Many dashboards share a complex outer wrapper (like a 300px left Sidebar and a top User Menu). The only thing that changes is the center panel.
Instead of copy/pasting the Sidebar into 50 different files, you generate a Nested Route Layout utilizing the <Outlet /> component.
// 1. Creating the Shell (The Main Layout)
import { Outlet } from 'react-router-dom';
function DashboardLayout() {
return (
<div style={{ display: 'flex' }}>
<LeftSidebar />
<main>
{/* The OUTLET is a black hole. React Router will inject children routes here! */}
<Outlet />
</main>
</div>
);
}
// 2. Defining the Nested Hierarchy in App.js
<Routes>
{/* The parent route acts as the physical wrapper container */}
<Route path="/dashboard" element={<DashboardLayout />}>
{/* These children components are injected directly into the parent's <Outlet />! */}
<Route path="settings" element={<SettingsPanel />} />
<Route path="analytics" element={<AnalyticsPanel />} />
</Route>
</Routes>
If the user navigates to /dashboard/analytics, React wraps the AnalyticsPanel inside the DashboardLayout, providing a perfectly seamless SPA transition without destroying the running Sidebar state.
💡 Summary Lexicon
| Router Concept | Real-World Component Strategy |
|---|---|
<BrowserRouter> | The outer shell. Put it exactly once at the absolute root of App.js. |
<Routes> + <Route> | The mapping rules matching URLs to screen components. |
<Link to="/url"> | Replaces <a href> to prevent the browser from flashing/refreshing. |
useParams() | Hook to extract dynamic IDs out of the URL string (e.g. /users/42). |
useNavigate() | Hook to forcefully change the URL via Javascript logic (Redirects). |
<Outlet /> | A hollow placeholder inside a Layout component where child routes are dynamically injected. |