React Router
React Router v6 turns a single-page React app into a multi-page experience by mapping URL paths to components without full page reloads.
Setting Up the Router
Everything react-router-dom does starts with a router component wrapping your app. BrowserRouter uses the HTML5 History API, so the address bar shows real, shareable, bookmarkable URLs while React swaps components in and out under the hood — no full-page reload ever happens.
Defining Routes
Inside the router, a Routes component holds one or more Route elements. Each Route pairs a path with the element to render when the current URL matches that path. Routes scans its children top to bottom and renders only the first match, so order matters — more specific paths should come before catch-alls.
- BrowserRouter — wraps the app and syncs it with the browser's URL
- Routes — picks the single best-matching Route from its children
- Route — maps one path to one element
- Link — navigates without a full page reload
- NavLink — a Link that knows whether it points at the active URL
- useNavigate — navigate programmatically from event handlers or effects
- useParams — read dynamic segments (like :id) out of the current URL
Basic route setup
// NOTE: This example needs the "react-router-dom" package, which is not
// installed in this sandbox by default. Add it as a dependency to run this
// example as-is.
import { BrowserRouter, Routes, Route } from "react-router-dom";
// Home/About/Contact would normally live in their own files and be
// imported (import Home from "./Home"; etc.). They're defined inline here
// since this sandbox only runs a single file.
function Home() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Contact() {
return <h2>Contact</h2>;
}
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
<Route path="*" element={<h1>404: Page Not Found</h1>} />
</Routes>
</BrowserRouter>
);
}
export default App;
Use Link (or NavLink) instead of a plain anchor tag for in-app navigation. A regular <a href> forces the browser to request a brand-new document from the server; Link intercepts the click, updates the URL via the History API, and lets React re-render only the parts of the page that changed.
Link and NavLink
// NOTE: This example needs the "react-router-dom" package, which is not
// installed in this sandbox by default. Add it as a dependency to run this
// example as-is.
import { BrowserRouter, Link, NavLink } from "react-router-dom";
function NavBar() {
return (
<nav>
<Link to="/">Home</Link>
<NavLink
to="/about"
className={({ isActive }) => (isActive ? "link active" : "link")}
>
About
</NavLink>
<NavLink to="/contact">Contact</NavLink>
</nav>
);
}
// Link and NavLink must render inside a Router, so this wraps NavBar with
// BrowserRouter to make the example runnable on its own.
function App() {
return (
<BrowserRouter>
<NavBar />
</BrowserRouter>
);
}
export default App;
Programmatic navigation with useNavigate
// NOTE: This example needs the "react-router-dom" package, which is not
// installed in this sandbox by default. Add it as a dependency to run this
// example as-is.
import { MemoryRouter, Routes, Route, useNavigate, useParams } from "react-router-dom";
function UserProfile() {
const { userId } = useParams();
const navigate = useNavigate();
function handleLogout() {
navigate("/login", { replace: true });
}
return (
<div>
<h2>Profile for user {userId}</h2>
<button onClick={handleLogout}>Log out</button>
<button onClick={() => navigate(-1)}>Go back</button>
</div>
);
}
function LoginPage() {
return <h2>Logged out</h2>;
}
// useNavigate/useParams need routing context. MemoryRouter with a fixed
// initial entry (instead of BrowserRouter) makes the /user/:userId param
// available immediately without depending on the sandbox's real URL.
function App() {
return (
<MemoryRouter initialEntries={["/user/42"]}>
<Routes>
<Route path="/user/:userId" element={<UserProfile />} />
<Route path="/login" element={<LoginPage />} />
</Routes>
</MemoryRouter>
);
}
export default App;
Exercise: React Router
Why use <Link> instead of a plain <a> tag for in-app navigation?