A loader and pending UI
The first loader runs before Root renders at all (the HydrateFallback shows meanwhile). On the click, Root re-renders with loading while the URL still says /users/1 and Asha stays (dimmed) on screen; only when Ravi's data arrives does the page switch.
In data mode you define routes as objects with createBrowserRouter (or createMemoryRouter) and render them with <RouterProvider>; each route can have a loader that fetches its data before it renders, an action that handles its <Form> submissions, and an errorElement for failures, while useNavigation() tells you when a navigation is pending.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 6 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Create a memory data router with a /posts route whose loader returns three post titles after 200 ms, and render them with useLoaderData.
Add a newsletter <Form method="post"> with an email field to a route; the action returns { error } when the email has no @, and { ok: true } otherwise. Show the right message.
Make a /posts/:id loader throw a 404 response for unknown ids and show Post not found from an errorElement.
Explain it without notes
What problem do loaders solve compared with fetching in useEffect?
Walk through what happens when a <Form method="post"> is submitted in a data router.
How do you show pending UI during navigations, and why does the old page stay visible?
How do errors work in data routers, and how do you tell a 404 from a crash?
Preview
Console
Nothing logged yet.Expected console output
loader: fetching user 1
Root: idle /users/1
loader: fetching user 2
Root: loading /users/1
Root: idle /users/2