The objects passed to createBrowserRouter
are called Route Objects.
createBrowserRouter([
{
path: "/",
Component: App,
},
]);
Route modules are the foundation of React Router's data features, they define:
This guide is a quick overview of every route object feature.
The Component
property in a route object defines the component that will render when the route matches.
createBrowserRouter([
{
path: "/",
Component: MyRouteComponent,
},
]);
function MyRouteComponent() {
return (
<div>
<h1>Look ma!</h1>
<p>
I'm still using React Router after like 10 years.
</p>
</div>
);
}
loader
Route loaders provide data to route components before they are rendered.
import {
useLoaderData,
createBrowserRouter,
} from "react-router";
createBrowserRouter([
{
path: "/",
loader: loader,
Component: MyRoute,
},
]);
async function loader({ params }) {
return { message: "Hello, world!" };
}
function MyRoute() {
let data = useLoaderData();
return <h1>{data.message}</h1>;
}
See also:
action
Route actions allow server-side data mutations with automatic revalidation of all loader data on the page when called from <Form>
, useFetcher
, and useSubmit
.
import {
createBrowserRouter,
useLoaderData,
useActionData,
Form,
} from "react-router";
import { TodoList } from "~/components/TodoList";
createBrowserRouter([
{
path: "/items",
action: action,
loader: loader,
Component: Items,
},
]);
async function action({ request }) {
const data = await request.formData();
const todo = await fakeDb.addItem({
title: data.get("title"),
});
return { ok: true };
}
// this data will be revalidated after the action completes...
async function loader() {
const items = await fakeDb.getItems();
return { items };
}
// ...so that the list here is updated automatically
export default function Items() {
let data = useLoaderData();
return (
<div>
<List items={data.items} />
<Form method="post" navigate={false}>
<input type="text" name="title" />
<button type="submit">Create Todo</button>
</Form>
</div>
);
}
shouldRevalidate
Loader data is automatically revalidated after certain events like navigations and form submissions.
This hook enables you to opt in or out of the default revalidation behavior. The default behavior is nuanced to avoid calling loaders unnecessarily.
A route loader is revalidated when:
By defining this function, you opt out of the default behavior completely and can manually control when loader data is revalidated for navigations and form submissions.
import type { ShouldRevalidateFunctionArgs } from "react-router";
function shouldRevalidate(
arg: ShouldRevalidateFunctionArgs
) {
return true; // false
}
createBrowserRouter([
{
path: "/",
shouldRevalidate: shouldRevalidate,
Component: MyRoute,
},
]);
ShouldRevalidateFunctionArgs
Reference Documentation ↗
Please note the default behavior is different in Framework Mode.
lazy
Most properties can be lazily imported to reduce the initial bundle size.
createBrowserRouter([
{
path: "/app",
lazy: async () => {
// load component and loader in parallel before rendering
const [Component, loader] = await Promise.all([
import("./app"),
import("./app-loader"),
]);
return { Component, loader };
},
},
]);
Next: Data Loading