π¦React Router Deep Dive: Build Modern, Navigable SPAs with Ease
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
BrowserRouterto wrap your app.Define navigation with
Link.Organize views with
RoutesandRoute.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
Outletfor 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