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

Continue with React Router v7

Save the full cheat sheet or work through every related task.

More React tasks

Back to the full React Router v7 cheat sheet