React Router Basics
Introduction
React Router adds client-side routing—change URLs without full page reloads and render different components per path. This chapter installs React Router, configures createBrowserRouter, uses Link / NavLink, dynamic params, and programmatic navigation with useNavigate.
Prerequisites
Install
bash
npm install react-router-domRouter Setup
src/router.tsx:
tsx
src/main.tsx:
tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { RouterProvider } from "react-router-dom";
import { router } from "./router";
import "./index.css";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<RouterProvider router={router} />
</StrictMode>
);Code explanation:
createBrowserRouteruses the History API—real URLs like/aboutRouterProviderrenders matched routes- Production needs server
try_filesfallback—Build and Deploy
Compare Vue Router Basics and History API.
Layout with Outlet
src/layouts/RootLayout.tsx:
tsx
<Outlet /> renders the active child route—like Vue <RouterView>.
NavLink Active State
tsx
import { NavLink } from "react-router-dom";
<NavLink
to="/about"
className={({ isActive }) => (isActive ? "nav active" : "nav")}
>
About
</NavLink>Dynamic Params
src/pages/PostDetailPage.tsx:
tsx
import { useParams } from "react-router-dom";
export function PostDetailPage() {
const { slug } = useParams<{ slug: string }>();
return <h1>Post: {slug}</h1>;
}Navigate programmatically:
tsx
import { useNavigate } from "react-router-dom";
function SearchResult({ slug }: { slug: string }) {
const navigate = useNavigate();
return (
<button type="button" onClick={() => navigate(`/posts/${slug}`)}>
Open post
</button>
);
}With state:
tsx
navigate("/checkout", { state: { from: "cart" } });Read with useLocation().state.
Query Strings
tsx
import { useSearchParams } from "react-router-dom";
function PostList() {
const [searchParams, setSearchParams] = useSearchParams();
const page = Number(searchParams.get("page") ?? "1");
function goToPage(next: number) {
setSearchParams({ page: String(next) });
}
return <p>Page {page}</p>;
}404 Route
tsx
{
path: "*",
element: <NotFoundPage />,
}Place catch-all last in the route tree.
Route Object Fields
| Field | Purpose |
|---|---|
path | URL segment |
element | Component to render |
children | Nested routes |
index: true | Default child at parent path |
loader | Data before render — chapter 14 |
FAQ
HashRouter vs BrowserRouter?
HashRouter (#/about) needs no server config—legacy hosting. Prefer createBrowserRouter for modern SPAs.
Relative links?
tsx
<Link to="settings">Settings</Link> // relative to current routeMultiple routers?
One RouterProvider per app.
React Router in tests?
Wrap with MemoryRouter — Testing.