React Router: A Comprehensive Guide to Navigation in React Apps

Prince DanielPrince Daniel
4 min read

Navigation is a critical part of any web application, providing users with seamless transitions between different views. In React applications, routing is handled using React Router, a powerful library that allows developers to define and manage navigation declaratively.

We’ll explore React Router v6, its key features, and best practices for implementing navigation in React apps.


πŸš€ What is React Router?

React Router is a client-side routing library for React that enables seamless navigation without reloading the page. It uses the History API to update the browser URL and render components based on the current route.

πŸ”₯ What's New in React Router v6?

React Router v6 introduces several improvements over previous versions:

βœ… Simpler API – Fewer components, improved readability
βœ… Nested Routes – Better support for component-based architecture
βœ… Route-Based Code Splitting – Optimize loading performance
βœ… Improved useNavigate Hook – Easier programmatic navigation


πŸ“¦ Installing React Router

To use React Router in your React project, install it via npm or yarn:

    npm install react-router-dom

or

    yarn add react-router-dom

πŸ›  Setting Up React Router

To enable routing, wrap your app inside the <BrowserRouter> component in index.js or App.js:

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

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

πŸ›€ Defining Routes

The Routes and Route components are used to define paths and render corresponding components.

import { Routes, Route } from 'react-router-dom';
import Home from './Home';
import About from './About';
import Contact from './Contact';

function App() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
      <Route path="/contact" element={<Contact />} />
    </Routes>
  );
}

export default App;

πŸ”Ή Key Changes from v5 to v6

  • Switch is replaced with Routes
  • Component prop is replaced with element

❌ v5: <Route path="/about" component={About} />
βœ… v6: <Route path="/about" element={<About />} />


Instead of <a> tags (which cause full-page reloads), use React Router’s <Link> component to navigate between pages:

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>
      </ul>
    </nav>
  );
}

export default Navbar;

πŸ”„ Programmatic Navigation

React Router provides the useNavigate hook for navigation within components:

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

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

  return (
    <div>
      <h1>Welcome to Home</h1>
      <button onClick={() => navigate('/about')}>Go to About</button>
    </div>
  );
}

export default Home;

πŸ“‚ Nested Routes

React Router v6 makes it easier to define nested routes, improving component organization:

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

function App() {
  return (
    <Routes>
      <Route path="/" element={<Layout />}>
        <Route index element={<Home />} />
        <Route path="about" element={<About />} />
        <Route path="contact" element={<Contact />} />
      </Route>
    </Routes>
  );
}

πŸ” How It Works:

  • The Layout component serves as a wrapper (e.g., a shared navbar).
  • The index route corresponds to /.
  • Subroutes (like /about) inherit the layout.

Layout.js:

import { Outlet } from 'react-router-dom';
import Navbar from './Navbar';

function Layout() {
  return (
    <div>
      <Navbar />
      <Outlet />
    </div>
  );
}

export default Layout;

πŸ”Ή The <Outlet /> component renders child routes dynamically inside Layout.


⚑ Route Parameters and Dynamic Routes

React Router supports route parameters, making it easy to create dynamic pages:

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

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

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

Define the dynamic route:

<Route path="/products/:id" element={<ProductDetail />} />

Visiting /products/123 will display Product ID: 123.


πŸ— Redirects and 404 Pages

Use the Navigate component to redirect users:

import { Navigate } from 'react-router-dom';

<Route path="*" element={<Navigate to="/" />} />

For a custom 404 page:

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

<Route path="*" element={<NotFound />} />

πŸ“Œ Protected Routes (Authentication)

To restrict access to specific routes, use protected routes with authentication logic:

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

function PrivateRoute({ isAuthenticated }) {
  return isAuthenticated ? <Outlet /> : <Navigate to="/login" />;
}

Use it in Routes:

<Route path="/dashboard" element={<PrivateRoute isAuthenticated={true} />}>
  <Route path="" element={<Dashboard />} />
</Route>

🎭 Lazy Loading with React Router

For better performance, lazy load routes using React's lazy() and Suspense:

import { lazy, Suspense } from 'react';
import { Routes, Route } from 'react-router-dom';

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

function App() {
  return (
    <Suspense fallback={<h1>Loading...</h1>}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Suspense>
  );
}

🎯 Summary

πŸš€ React Router v6 simplifies routing with a modern API, making navigation more efficient. Here’s a quick recap:

βœ… Use Routes instead of Switch
βœ… Use useNavigate instead of useHistory
βœ… Implement nested routes using <Outlet />
βœ… Use lazy loading for better performance
βœ… Secure routes with protected routes

By leveraging React Router effectively, you can build fast, scalable, and intuitive React applications. Happy coding! πŸŽ‰


0
Subscribe to my newsletter

Read articles from Prince Daniel directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Prince Daniel
Prince Daniel

Passionate about AI, software engineering, and data-driven innovation, I specialize in building intelligent solutions that bridge technology and real-world impact. With a background in Electrical and Telecommunication Engineering, I have experience leading AI-driven projects, managing cross-functional teams, and transforming research into scalable applications. I write about AI, cloud computing, product management, and the evolving landscape of software engineeringβ€”breaking down complex concepts and exploring how emerging technologies shape industries. Join me as we navigate the ever-changing world of tech and innovation. πŸš€ #AI #SoftwareEngineering #Innovation #ProductManagement #BusinessDevelopment