Everything You Need to Know About React Routing

Routing is an essential part of web applications, enabling users to navigate between different pages or sections of a single-page application (SPA) without requiring a full page reload. React, one of the most popular JavaScript libraries for building user interfaces, provides robust support for routing through the React Router library.

In this guide, we’ll explore routing in React, including the ability to define multiple routes, implement nested and dynamic routes, and handle common scenarios like protected routes and 404 pages.

What is Routing in React?

Routing in React allows developers to map URLs to specific components and dynamically load content based on the user's interaction. Unlike traditional multi-page apps, SPAs handle routing on the client side, providing a smoother user experience.

Why React Router?

React Router is the go-to library for routing in React applications due to its flexibility and rich feature set. Key benefits include:

Declarative Approach: Define routes using components.

Multiple Routes: Manage multiple routes easily.

Nested Routes: Support for hierarchical layouts.

Dynamic Routing: Handle dynamic paths with ease (e.g., /user/:id).

404 Handling: Provide fallback routes for undefined paths.

Core Components of React Router

BrowserRouter: Synchronizes the UI with the URL.

Routes: Encapsulates all route definitions.

Route: Maps a path to a component.

Link: A component used for navigation without full-page reloads.

Outlet: A placeholder for nested routes.

Navigate: Redirects users programmatically.

Setting Up Routing in React

Here’s how you can implement routing step by step, including handling multiple routes and using nested components like Dashboard.

Step 1: Install React Router

Install React Router using npm or yarn:

npm install react-router-dom

Step 2: Wrap Your Application with BrowserRouter

In your index.js, wrap the root component with BrowserRouter:

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from './App';

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

Step 3: Define Routes (Including Multiple and Nested Routes)

In App.js, define routes for different components, including nested routes within a Dashboard component:

import React from 'react';
import { Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';
import Contact from './pages/Contact';
import Dashboard from './pages/Dashboard';
import Analytics from './pages/Analytics';
import Settings from './pages/Settings';
import NotFound from './pages/NotFound';

function App() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
      <Route path="/contact" element={<Contact />} />
      {/* Dashboard with nested routes */}
      <Route path="/dashboard" element={<Dashboard />}>
        <Route path="analytics" element={<Analytics />} />
        <Route path="settings" element={<Settings />} />
      </Route>
      {/* 404 Page */}
      <Route path="*" element={<NotFound />} />
    </Routes>
  );
}
export default App;

Step 4: Create the Dashboard Component with Navigation and Nested Routes

The Dashboard component serves as a parent for nested routes. It includes navigation links for the nested pages (Analytics and Settings) and uses Outlet to render the child components.

import React from 'react';
import { Outlet, Link } from 'react-router-dom';

function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      <nav>
        <ul>
          <li>
            <Link to="/dashboard/analytics">Analytics</Link>
          </li>
          <li>
            <Link to="/dashboard/settings">Settings</Link>
          </li>
        </ul>
      </nav>
      {/* Render nested routes */}
      <Outlet />
    </div>
  );
}

export default Dashboard;

Now, when users navigate to /dashboard, they will see the Dashboard component with links to Analytics and Settings. Clicking these links will render the corresponding nested components in place of the Outlet.

Step 5: Create Nested Components (Analytics and Settings)

Define components for the nested routes under the Dashboard:

Analytics.js:

function Analytics() {
  return <h2>Analytics Page</h2>;
}
export default Analytics;

Settings.js:

function Settings() {
  return <h2>Settings Page</h2>;
}
export default Settings

Step 6: Handle Undefined Routes (404 Page)

Create a fallback component for undefined routes:

NotFound.js:

function NotFound() {
  return <h1>404 - Page Not Found</h1>;
}
export default NotFound;

Step 7: Add Global Navigation

Include a navigation bar in your application to access the main routes, including the Dashboard:

import React from 'react';
import { Link } from 'react-router-dom';

function Navbar() {
  return (
    <nav>
      <ul>
        <li>
          <Link to="/">Home</Link>
        </li>
        <li>
          <Link to="/about">About</Link>
        </li>
        <li>
          <Link to="/contact">Contact</Link>
        </li>
        <li>
          <Link to="/dashboard">Dashboard</Link>
        </li>
      </ul>
    </nav>
  );
}
export default Navbar;

Step 8: Use the Navbar in the Application

Include the Navbar at the top of your application:

import Navbar from './components/Navbar';

function App() {
  return (
    <>
      <Navbar />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
        <Route path="/dashboard" element={<Dashboard />}>
          <Route path="analytics" element={<Analytics />} />
          <Route path="settings" element={<Settings />} />
        </Route>
        <Route path="*" element={<NotFound />} />
      </Routes>
    </>
  );
}
export default App;

Key Takeaways

Multiple Routes: Define multiple routes for various pages, including nested routes.

Reusable Components: Components like Dashboard and Navbar organize code better.

Dynamic Navigation: Use Link for smooth, reload-free navigation.

Error Handling: Always include a fallback for undefined routes.

Conclusion

By leveraging React Router, you can efficiently handle routing in your applications. This includes managing multiple and nested routes, creating reusable navigation components, and providing fallback pages for undefined paths. Mastering these concepts ensures a scalable and user-friendly React application.