React Router v6 Data Loaders and Actions0%

React Router v6 Data Loaders and Actions

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

React Router v6 Data Loaders and Actions

1. The Shift to Data-Driven Routing

Historically in React SPAs, data fetching followed the "Fetch-on-Render" pattern:

  1. 1
    The user navigates to /courses/react.
  2. 2
    React Router mounts <CourseDetail />.
  3. 3
    The component renders empty markup with a loading spinner.
  4. 4
    An inner useEffect fires across the network to fetch the course.
  5. 5
    300ms later, data arrives and the component re-renders with actual content.

This sequential waterfall (Route changes -> Component renders -> Effect fires -> Data arrives) introduces noticeable UI delay and layout shifts.

In modern React Router (v6.4+), routing shifted to Data Routers:

Data fetching and route matching happen in PARALLEL before the component is ever rendered!
Output
Old Fetch-on-Render:
[Route Changes] ──► [Component Mounts (Blank)] ──► [useEffect Fires] ──► [Data Arrives] (Slow Waterfall)
 
Modern Data Loaders:
[Route Changes] ──► [Loader Fetches Data & Components Load in Parallel] ──► [Render Complete UI Instantly!]

2. Setting Up a Data Router with createBrowserRouter

To use Data Loaders, you must configure your router using createBrowserRouter and RouterProvider:

JSX
// src/router.jsx
import { createBrowserRouter } from 'react-router-dom';
import RootLayout from './layouts/RootLayout';
import CourseCatalog, { courseLoader } from './pages/CourseCatalog';
import CourseDetail, { courseDetailLoader } from './pages/CourseDetail';
 
export const router = createBrowserRouter([
{
path: '/',
element: <RootLayout />,
children: [
{
path: 'courses',
element: <CourseCatalog />,
loader: courseLoader // Data loader function!
},
{
path: 'courses/:slug',
element: <CourseDetail />,
loader: courseDetailLoader // Receives params automatically!
}
]
}
]);

3. Implementing a Route Loader

A loader is a standard JavaScript function that returns data or a Promise:

JSX
// src/pages/CourseDetail.jsx
import React from 'react';
import { useLoaderData } from 'react-router-dom';
 
// 1. The Loader Function (Runs BEFORE component renders!)
export async function courseDetailLoader({ params }) {
const response = await fetch(`/api/courses/${params.slug}`);
 
if (!response.ok) {
// Throwing a Response triggers the route's errorElement!
throw new Response('Course Not Found', { status: 404 });
}
 
return response.json(); // Returning data directly
}
 
// 2. The Component consuming the data
export default function CourseDetail() {
// Extracts data returned by loader synchronously!
const course = useLoaderData();
 
return (
<div className="course-view">
<h2>{course.title}</h2>
<p>{course.description}</p>
<span className="badge">${course.price}</span>
</div>
);
}

4. Route Actions for Form Mutations

React Router also introduces Actions for data mutations (POST, PUT, DELETE), modeling HTML form behavior:

JSX
import { Form, redirect } from 'react-router-dom';
 
// Action handles form submission
export async function courseAction({ request }) {
const formData = await request.formData();
const title = formData.get('title');
 
await fetch('/api/courses', {
method: 'POST',
body: JSON.stringify({ title })
});
 
// Redirect to catalog after mutation
return redirect('/courses');
}
 
export function CreateCourse() {
return (
// React Router's <Form> component posts directly to the action!
<Form method="post">
<input type="text" name="title" required />
<button type="submit">Create Course</button>
</Form>
);
}

Interactive Quiz

Practice Quiz

Question 1
How do Data Loaders in React Router v6.4+ eliminate data-fetching waterfalls?
Question 2
What hook is used inside a route component to access the data returned by its loader?
Question 3
What router configuration function is mandatory to enable Data Loaders and Actions in React Router?
Question 4
What happens if a loader function throws a new Response('Not Found', { status: 404 })?
Question 5
How do React Router Actions handle form submissions?
Next Lesson

Deferred Data and Suspense Streaming with Await

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext