0
0
RemixDebug / FixBeginner · 4 min read

How to Handle Loading State in Remix: Simple Guide

In Remix, handle loading state by using the useTransition hook to detect navigation progress and conditionally render a loading indicator. This approach keeps the UI responsive by showing feedback during data loading or page transitions.
🔍

Why This Happens

When you navigate between routes or submit forms in Remix, the UI might not show any feedback that something is loading. This happens because Remix does not automatically display a loading state, so users may think the app is frozen or slow.

Developers often forget to handle this state explicitly, causing confusion.

jsx
import { useLoaderData } from "@remix-run/react";

export default function Posts() {
  const posts = useLoaderData();

  return (
    <div>
      <h1>Posts</h1>
      <ul>
        {posts.map(post => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}
Output
UI shows posts list but no loading indicator during navigation or data fetching.
🔧

The Fix

Use Remix's useTransition hook to detect when a navigation or form submission is in progress. Then, conditionally render a loading message or spinner to inform users that the app is working.

This improves user experience by providing immediate feedback.

jsx
import { useLoaderData, useTransition } from "@remix-run/react";

export default function Posts() {
  const posts = useLoaderData();
  const transition = useTransition();
  const isLoading = transition.state === "loading" || transition.state === "submitting";

  return (
    <div>
      <h1>Posts</h1>
      {isLoading ? (
        <p>Loading posts...</p>
      ) : (
        <ul>
          {posts.map(post => (
            <li key={post.id}>{post.title}</li>
          ))}
        </ul>
      )}
    </div>
  );
}
Output
When navigating or submitting, the UI shows 'Loading posts...' until data is ready, then displays the posts list.
🛡️

Prevention

Always plan for loading states in your Remix components that fetch data or handle navigation. Use useTransition to detect loading and show feedback.

Keep loading indicators simple and accessible, using semantic HTML and ARIA roles if needed.

Consider adding global loading UI in your root layout for consistent experience.

⚠️

Related Errors

Developers sometimes confuse useLoaderData with loading state, expecting it to handle loading UI automatically.

Another common mistake is not checking transition.state properly, causing loading indicators to never show or stay forever.

Key Takeaways

Use Remix's useTransition hook to detect loading or submitting states.
Render a loading indicator conditionally during navigation or data fetch.
Plan loading states in every component that fetches data or handles forms.
Keep loading UI simple, accessible, and consistent across your app.