Routing is a fundamental aspect of building multi-page applications with React. It allows users to navigate between different views or components without a full page reload, providing a smoother and more dynamic user experience. React Router is the most popular library for handling routing in React applications.
Core Concepts
- Routes: Define the mapping between a URL path and a React component. When the browser's URL matches a route's path, the corresponding component is rendered.
- Links: Used to navigate between routes. Instead of using standard
<a href="...">tags, React Router provides the<Link>component. This prevents full page reloads and leverages React's component rendering. BrowserRouter(orHashRouter): Wraps your application and enables routing functionality.BrowserRouteruses the browser's history API (clean URLs), whileHashRouteruses the hash portion of the URL (e.g.,your-app.com/#/about).BrowserRouteris generally preferred for production.Routes: A container for individualRoutecomponents. It ensures that only the first matching route is rendered.Route: Defines a single route, specifying the path and the component to render when that path is matched.useNavigate: A hook that provides access to the navigation object, allowing programmatic navigation.
Implementation with React Router v6
Here's a basic example demonstrating how to set up routing with React Router v6:
1. Installation:
npm install react-router-dom
# or
yarn add react-router-dom
2. App.js (or your main application component):
import React from 'react';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
function Home() {
return (
<div>
<h2>Home</h2>
<p>Welcome to the homepage!</p>
</div>
);
}
function About() {
return (
<div>
<h2>About</h2>
<p>Learn more about us.</p>
</div>
);
}
function Contact() {
return (
<div>
<h2>Contact</h2>
<p>Get in touch with us.</p>
</div>
);
}
function App() {
return (
<BrowserRouter>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</BrowserRouter>
);
}
export default App;
Explanation:
BrowserRouter: Wraps the entire application, enabling routing.Link: Creates navigation links. Thetoprop specifies the path to navigate to.Routes: Contains the individualRoutecomponents.Route: EachRoutecomponent defines a path and the component to render when that path is matched. Theelementprop specifies the component.
Dynamic Routes (Route Parameters)
To create routes that accept parameters (e.g., /products/:id), you can use dynamic segments in the path:
import React from 'react';
import { BrowserRouter, Routes, Route, Link, useParams } from 'react-router-dom';
function ProductDetail() {
let { productId } = useParams(); // Access the 'id' parameter
return (
<div>
<h2>Product Detail</h2>
<p>Product ID: {productId}</p>
</div>
);
}
function App() {
return (
<BrowserRouter>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/products/123">Product 123</Link>
</li>
<li>
<Link to="/products/456">Product 456</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/products/:productId" element={<ProductDetail />} />
</Routes>
</BrowserRouter>
);
}
export default App;
Explanation:
/products/:productId: The:productIdis a dynamic segment. It will match any value in that position.useParams(): A hook that allows you to access the values of the dynamic segments in the URL. In this case,productIdwill contain the value of theidparameter.
Programmatic Navigation with useNavigate
The useNavigate hook allows you to navigate programmatically within your components:
import React from 'react';
import { BrowserRouter, Routes, Route, Link, useNavigate } from 'react-router-dom';
function Login() {
let navigate = useNavigate();
const handleSubmit = (event) => {
event.preventDefault();
// Simulate login success
navigate('/dashboard'); // Navigate to the dashboard after login
};
return (
<div>
<h2>Login</h2>
<form onSubmit={handleSubmit}>
{/* Login form fields */}
<button type="submit">Login</button>
</form>
</div>
);
}
function App() {
return (
<BrowserRouter>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/login">Login</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/dashboard" element={<div>Dashboard</div>} />
</Routes>
</BrowserRouter>
);
}
export default App;
Explanation:
useNavigate(): Returns a navigation object.navigate('/dashboard'): Programmatically navigates to the/dashboardroute.
Nested Routes
You can create nested routes to represent hierarchical relationships in your application:
import React from 'react';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
function Dashboard() {
return (
<div>
<h2>Dashboard</h2>
<ul>
<li><Link to="overview">Overview</Link></li>
<li><Link to="settings">Settings</Link></li>
</ul>
<Routes>
<Route path="overview" element={<div>Dashboard Overview</div>} />
<Route path="settings" element={<div>Dashboard Settings</div>} />
</Routes>
</div>
);
}
function App() {
return (
<BrowserRouter>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/dashboard">Dashboard</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/" element={<div>Home</div>} />
<Route path="/dashboard" element={<Dashboard />} />
</Routes>
</BrowserRouter>
);
}
export default App;
Explanation:
- The
Dashboardcomponent has its ownRoutesandRoutecomponents, defining sub-routes within the dashboard. - The
Linkcomponents withinDashboarduse relative paths (e.g.,to="overview") to navigate within the dashboard's routes.
Resources
- React Router Documentation: https://reactrouter.com/
This provides a solid foundation for understanding and implementing routing in your React applications. Remember to consult the official React Router documentation for more advanced features and options.