Skip to main content

Why loading states matter

When your app fetches data, there’s a gap between clicking and seeing results. Without a loading state, users see either nothing (blank screen) or stale data. They don’t know if the app is working.

The loading state pattern

Every data-fetching component needs three states: loading, error, and data.
This is the pattern you’ll use in almost every component that fetches data. Three states, three checks at the top of the return.
Notice the order: check loading first, then error, then empty state, then render data. This order matters because you want to show the most relevant state.

Loading indicators

Simple text

Spinner component

Inline loading (inside existing content)

Use full-page loading for initial loads and inline loading for refreshes. If the user already sees data, don’t replace it with a spinner — show the spinner alongside the existing content.

Disabling buttons during requests

Prevent users from double-clicking submit buttons:
Key details:
  • disabled={submitting} prevents the button from being clicked again
  • Button text changes to show progress (“Creating…”)
  • Input is also disabled to prevent editing during submission
  • finally ensures the button re-enables even if the request fails
Always disable submit buttons during requests. Without this, users can click multiple times and create duplicate entries. This is one of the most common bugs in web applications.

The complete data fetching pattern

This is the pattern you’ll reuse across your entire application:
This three-state pattern (loading / error / data) shows up so often that libraries like React Query and SWR were created to automate it. For now, writing it manually teaches you what’s happening under the hood.

Refactoring into a custom hook

Once you’re comfortable with the pattern, extract it into a reusable hook:
One hook, any endpoint. The same loading/error/data pattern without repeating yourself.

What’s next?

You’ve covered the complete async & APIs section — from understanding async JavaScript to making real API calls with proper error handling and loading states. Next up: the DOM and browser APIs. You’ll learn how JavaScript interacts with the page itself — selecting elements, modifying content, and responding to user actions.

What is the DOM?

Understand how JavaScript sees and interacts with your page