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

More React tasks

Back to the full React Router v7 cheat sheet