React Router
React Router (v6) is the standard client-side routing library for React. It lets you map URLs to components and navigate between them without page reloads.
npm install react-router-dom
Basic Setup
// main.jsx
import { BrowserRouter } from "react-router-dom";
ReactDOM.createRoot(document.getElementById("root")).render(
<BrowserRouter><App /></BrowserRouter>
);
// App.jsx
import { Routes, Route, Navigate } from "react-router-dom";
function App() {
return (
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="about" element={<About />} />
<Route path="users" element={<UserList />} />
<Route path="users/:id" element={<UserDetail />} />
<Route path="*" element={<Navigate to="/" replace />} />
</Route>
<Route path="/login" element={<Login />} />
</Routes>
);
}
Layout with Outlet
import { Outlet, NavLink } from "react-router-dom";
function Layout() {
return (
<div>
<nav>
{/* NavLink adds className "active" automatically to the current route */}
<NavLink to="/">Home</NavLink>
<NavLink to="/about">About</NavLink>
<NavLink to="/users">Users</NavLink>
</nav>
<main>
<Outlet /> {/* Child route renders here */}
</main>
</div>
);
}
Router Hooks
// useParams โ read URL parameters
function UserDetail() {
const { id } = useParams(); // /users/42 โ id = "42"
const { data: user } = useFetch(`/api/users/${id}`);
return <div>{user?.name}</div>;
}
// useNavigate โ programmatic navigation
function LoginForm() {
const navigate = useNavigate();
const handleLogin = async () => {
await login(credentials);
navigate("/dashboard", { replace: true });
};
}
// useSearchParams โ query string (?page=2&sort=name)
function ProductList() {
const [params, setParams] = useSearchParams();
const page = parseInt(params.get("page") ?? "1");
const setPage = (n) => setParams({ page: n });
}
Protected Route
function RequireAuth({ children }) {
const { user } = useAuth();
const location = useLocation();
if (!user) {
// Redirect to login, save intended destination in state
return <Navigate to="/login" state={{ from: location }} replace />;
}
return children;
}
// Wrap any route that needs auth
<Route path="dashboard" element={<RequireAuth><Dashboard /></RequireAuth>} />