React Router Cheatsheet

Navigation and Links

Use this React Router reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

Imperative Navigation

import { useNavigate } from "react-router";

const navigate = useNavigate();

navigate("/dashboard");
navigate("/dashboard", { replace: true });
navigate(-1);                        // back
navigate(1);                         // forward
navigate("/edit", { state: { draft } });
navigate({ pathname: "/list", search: "?page=2" });
navigate("/save", { flushSync: true });
navigate(".", { replace: true });     // re-resolve the current route

Reach for useNavigate in event handlers only. For a redirect that depends on data, return redirect() from a loader or action instead, and for a link, render a Link so the browser gets a real href.

import { Navigate } from "react-router";

// declarative redirect on render, useful in a guard component
if (!user) return <Navigate to="/login" replace />;

Redirects from Loaders and Actions

HelperEffect
redirect(url, init?)302 by default, client side navigation
redirect(url, 301)Pass a number for the status
redirectDocument(url)Full document load, use for a route outside the app
replace(url)Redirect that replaces the history entry
import { redirect } from "react-router";
import type { Route } from "./+types/dashboard";

export async function loader({ request }: Route.LoaderArgs) {
  const user = await getUser(request);
  if (!user) throw redirect("/login");
  return { user };
}

Throwing is the idiom inside a helper function, since it stops execution at the call site. Returning the redirect works too when it is the last statement in the loader.

Pending UI

import { useNavigation, useRevalidator } from "react-router";

function GlobalSpinner() {
  const navigation = useNavigation();
  const busy = navigation.state !== "idle";
  return busy ? <div className="bar" /> : null;
}
ReadValue
navigation.stateidle, loading, or submitting
navigation.locationWhere the app is heading, undefined when idle
navigation.formDataThe submitted FormData, for optimistic UI
navigation.formMethodget, post, put, patch, delete
useRevalidator().revalidate()Re-run every loader on the page
useRevalidator().stateidle or loading

Framework mode also lets a route export HydrateFallback for the initial client load, so pending UI splits into two cases: first paint and later navigations.