What is React Router?

  • React Router is a standard library for routing in React applications. It enables navigation between different views or pages in a React app while maintaining a single-page application (SPA) behavior. It allows for dynamic URL mapping, nested routes, and easy management of navigation state.

Why Use React Router?

  • Client-side Routing: No need to reload the page when navigating.
  • Dynamic Routing: Routes are determined dynamically rather than being hardcoded.
  • Nested Routes: Supports layouts and sub-components.
  • Easy Redirection & Navigation: Programmatic navigation and redirects.
  • State Management Integration: Works well with Redux, Context API, etc.

1. Setting Up Routes

React Router provides a <BrowserRouter> component that enables routing in React applications.

import React from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
 
const Home = () => <h1>Home Page</h1>;
const About = () => <h1>About Page</h1>;
 
const App = () => {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Router>
  );
};
 
export default App;

Instead of using traditional <a> tags, React Router provides <Link> and <NavLink> components.

import { Link } from "react-router-dom";
 
const Navbar = () => {
  return (
    <nav>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
    </nav>
  );
};

  • Using NavLink for Active Styling
import { NavLink } from "react-router-dom";
 
const Navbar = () => {
  return (
    <nav>
      <NavLink
        to="/"
        style={({ isActive }) => ({ color: isActive ? "red" : "black" })}
      >
        Home
      </NavLink>
      <NavLink to="/about">About</NavLink>
    </nav>
  );
};

3. Dynamic Routing with URL Parameters

To pass dynamic values in URLs, use Route Parameters.

import { useParams } from "react-router-dom";
 
const UserProfile = () => {
  const { userId } = useParams();
  return <h1>User Profile: {userId}</h1>;
};
<Routes>
  <Route path="/user/:userId" element={<UserProfile />} />
</Routes>
// If you navigate to /user/123, it will display User Profile: 123.

4. Programmatic Navigation using useNavigate

React Router provides the useNavigate hook for navigation without using <Link>.

import { useNavigate } from "react-router-dom";
 
const Home = () => {
  const navigate = useNavigate();
 
  const goToAbout = () => {
    navigate("/about");
  };
 
  return (
    <div>
      <h1>Home Page</h1>
      <button onClick={goToAbout}>Go to About</button>
    </div>
  );
};

5. Nested Routes

For layout-based navigation, we use nested routes.

import { Outlet } from "react-router-dom";
 
const DashboardLayout = () => {
  return (
    <div>
      <h1>Dashboard</h1>
      <Outlet />
    </div>
  );
};
 
<Routes>
  <Route path="/dashboard" element={<DashboardLayout />}>
    <Route path="profile" element={<h2>Profile Page</h2>} />
    <Route path="settings" element={<h2>Settings Page</h2>} />
  </Route>
</Routes>;
// The <Outlet /> component renders the matched child route.

6. Redirects & Protected Routes

To protect routes (e.g., authentication-based), we can use a wrapper component.

import { Navigate } from "react-router-dom";
 
const ProtectedRoute = ({ isAuthenticated, children }) => {
  return isAuthenticated ? children : <Navigate to="/login" />;
};
 
<Routes>
  <Route
    path="/dashboard"
    element={
      <ProtectedRoute isAuthenticated={true}>
        <Dashboard />
      </ProtectedRoute>
    }
  />
</Routes>;

7. Handling 404 Not Found Pages

To show a β€œPage Not Found” error for unknown routes:

<Routes>
  <Route path="*" element={<h1>404 - Page Not Found</h1>} />
</Routes>

Note

  • Use BrowserRouter for standard routing.
  • Use NavLink instead of Link for better navigation experience.
  • Encapsulate layout-based routes using nested routes.
  • Use useNavigate instead of window.location.href.
  • Keep route definitions in a separate file for scalability.
  • Use a central file for route definitions in large projects.
  • Implement error boundaries and fallback UI for better UX.