Skip to main content

Command Palette

Search for a command to run...

🚦React Router Deep Dive: Build Modern, Navigable SPAs with Ease

Published
β€’4 min readβ€’View as Markdown

When building modern Single Page Applications (SPAs), client-side routing becomes essential. React, being a library for building user interfaces, doesn't include routing out of the box. That’s where React Router comes in β€” a powerful library that allows dynamic routing in React apps.

In this post, we’ll explore React Router (v6+), understand how it works, and build a sample navigable app with practical examples.


πŸ“¦ What is React Router?

React Router is a standard library for routing in React. It enables navigation among views of various components, allows changing the browser URL, and keeps the UI in sync with the URL.

✨ Key Features:

  • Nested Routing

  • Dynamic Routing

  • Route Parameters

  • Lazy Loading

  • Navigation Programmatically

  • Not Found Pages (404)

  • Route Protection


πŸ”§ Installation

Before diving in, install React Router in your React project:

npm install react-router-dom

Or with yarn:

yarn add react-router-dom

🧭 Basic Routing Example

Let’s start with a simple setup using BrowserRouter, Routes, and Route.

// App.jsx
import React from 'react';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';

function Home() {
  return <h2>🏠 Home Page</h2>;
}

function About() {
  return <h2>ℹ️ About Page</h2>;
}

function Contact() {
  return <h2>πŸ“ž Contact Page</h2>;
}

function App() {
  return (
    <BrowserRouter>
      <nav style={{ display: 'flex', gap: '1rem' }}>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
        <Link to="/contact">Contact</Link>
      </nav>

      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

Explanation:

  • BrowserRouter: Wraps your app and enables routing.

  • Link: Used instead of <a> to avoid full-page reloads.

  • Routes & Route: Define the component to render based on the URL.


πŸ” Nested Routes

React Router makes nesting routes easy.

// Dashboard.jsx
import { Outlet, Link } from 'react-router-dom';

function Dashboard() {
  return (
    <div>
      <h2>πŸ“Š Dashboard</h2>
      <nav>
        <Link to="profile">Profile</Link> | <Link to="settings">Settings</Link>
      </nav>
      <Outlet /> {/* Child components render here */}
    </div>
  );
}

// Inside App.jsx
<Route path="/dashboard" element={<Dashboard />}>
  <Route path="profile" element={<div>πŸ‘€ Profile</div>} />
  <Route path="settings" element={<div>βš™οΈ Settings</div>} />
</Route>

🧩 Route Parameters

You can pass parameters via the URL to create dynamic routes.

// User.jsx
import { useParams } from 'react-router-dom';

function User() {
  const { userId } = useParams();
  return <h3>User ID: {userId}</h3>;
}

// Inside App.jsx
<Route path="/user/:userId" element={<User />} />

Visit /user/123 and you'll see: User ID: 123


⏩ Redirects and Navigation

Use useNavigate() to navigate programmatically.

// Login.jsx
import { useNavigate } from 'react-router-dom';

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

  const handleLogin = () => {
    // Assume login success
    navigate('/dashboard');
  };

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

πŸ›‘ 404 Not Found Page

You can catch all unmatched routes:

<Route path="*" element={<h2>404 Page Not Found 🚫</h2>} />

πŸ” Protected Routes

For authentication-based routing:

// ProtectedRoute.jsx
import { Navigate } from 'react-router-dom';

function ProtectedRoute({ isAuthenticated, children }) {
  return isAuthenticated ? children : <Navigate to="/login" />;
}

// Inside App.jsx
<Route path="/admin" element={
  <ProtectedRoute isAuthenticated={loggedIn}>
    <AdminPanel />
  </ProtectedRoute>
} />

🧠 Lazy Loading Routes

Improve performance by loading components on demand.

import React, { lazy, Suspense } from 'react';

const LazyAbout = lazy(() => import('./About'));

<Route
  path="/about"
  element={
    <Suspense fallback={<div>Loading...</div>}>
      <LazyAbout />
    </Suspense>
  }
/>

πŸ§ͺ Final Project Structure

src/
β”œβ”€β”€ App.jsx
β”œβ”€β”€ index.js
β”œβ”€β”€ components/
β”‚   └── ProtectedRoute.jsx
β”œβ”€β”€ pages/
β”‚   β”œβ”€β”€ Home.jsx
β”‚   β”œβ”€β”€ About.jsx
β”‚   β”œβ”€β”€ Contact.jsx
β”‚   β”œβ”€β”€ Dashboard.jsx
β”‚   β”œβ”€β”€ Login.jsx
β”‚   └── User.jsx

βœ… Summary

React Router is an essential library for React developers building modern SPAs. Here's a recap:

  • Use BrowserRouter to wrap your app.

  • Define navigation with Link.

  • Organize views with Routes and Route.

  • Create dynamic URLs with parameters.

  • Use useNavigate() for programmatic redirects.

  • Protect routes using conditional rendering.

  • Optimize with lazy loading.


πŸ’‘ Pro Tips

  • Always keep your routes in sync with your component structure.

  • Use useLocation() for conditional UI based on route.

  • Prefer Outlet for nested routes to keep components clean.


🎯 Try This!

Mini challenge: Create a mini blog app with:

  • Home

  • Blog list (/blogs)

  • Individual blog post (/blogs/:id)

  • Protected "New Post" page that only shows when isLoggedIn === true