Loaders & Data Fetching in React
From the React Router v7 cheat sheet · Data Loading · verified Jul 2026
Loaders & Data Fetching
Loading data before rendering components
typescript
// Basic loader
export async function loader({ params }) {
const user = await fetchUser(params.userId)
if (!user) {
throw new Response("Not Found", { status: 404 })
}
return { user }
}
// Using loaded data
import { useLoaderData } from 'react-router'
export default function User() {
const { user } = useLoaderData<typeof loader>()
return <h1>{user.name}</h1>
}
// Defer streaming data
import { defer, Await } from 'react-router'
import { Suspense } from 'react'
export async function loader() {
return defer({
critical: await fetchCriticalData(),
slow: fetchSlowData() // Don't await
})
}
export default function Page() {
const { critical, slow } = useLoaderData<typeof loader>()
return (
<div>
<h1>{critical.title}</h1>
<Suspense fallback={<Loading />}>
<Await resolve={slow}>
{(data) => <SlowComponent data={data} />}
</Await>
</Suspense>
</div>
)
}💡 Use defer() to stream non-critical data for faster initial loads
⚡ Loaders run in parallel for nested routes automatically
📌 Throw responses for errors and redirects
🟢 Always handle loading states with Suspense for deferred data
loadersdatadeferstreaming