How to Show Pending State in Remix: Simple Guide
In Remix, you can show a pending state by using the
useTransition hook, which tracks navigation or form submission status. When transition.state is "submitting" or "loading", you can display a loading indicator or message to inform users that an action is in progress.Syntax
The useTransition hook returns an object with a state property that can be idle, submitting, or loading. You check this state to conditionally render UI elements like spinners or messages.
Example parts:
const transition = useTransition();- gets the current transition state.transition.state- the current status string.- Conditional rendering based on
transition.state.
jsx
import { useTransition } from "@remix-run/react"; function MyComponent() { const transition = useTransition(); if (transition.state === "submitting") { return <p>Submitting...</p>; } if (transition.state === "loading") { return <p>Loading...</p>; } return <p>Idle state</p>; }
Output
Idle state (or Submitting... / Loading... depending on transition.state)
Example
This example shows a simple form that displays a "Submitting..." message while the form is being sent, using useTransition. When the form is idle, it shows the submit button.
jsx
import { Form, useTransition } from "@remix-run/react"; export default function ContactForm() { const transition = useTransition(); const isSubmitting = transition.state === "submitting"; return ( <Form method="post"> <label htmlFor="message">Message:</label> <textarea id="message" name="message" required></textarea> <button type="submit" disabled={isSubmitting}> {isSubmitting ? "Submitting..." : "Send"} </button> </Form> ); }
Output
<form> with a textarea and a button that changes to 'Submitting...' and disables while submitting
Common Pitfalls
- Not checking both
submittingandloadingstates can cause missing feedback during navigation. - Disabling buttons without visual feedback can confuse users.
- Using
useTransitionoutside Remix components or without proper imports causes errors.
jsx
/* Wrong way: Not disabling button or showing feedback */ import { Form, useTransition } from "@remix-run/react"; function Wrong() { const transition = useTransition(); return ( <Form method="post"> <button type="submit">Send</button> </Form> ); } /* Right way: Disable and show submitting text */ function Right() { const transition = useTransition(); const isSubmitting = transition.state === "submitting"; return ( <Form method="post"> <button type="submit" disabled={isSubmitting}> {isSubmitting ? "Submitting..." : "Send"} </button> </Form> ); }
Quick Reference
| Term | Description |
|---|---|
| useTransition() | Hook to get current navigation or form submission state |
| transition.state | Current state: 'idle', 'submitting', or 'loading' |
| submitting | Form is being submitted |
| loading | Page or data is loading after navigation |
| idle | No active transition |
Key Takeaways
Use Remix's useTransition hook to detect pending states during navigation or form submissions.
Check transition.state for 'submitting' or 'loading' to show appropriate loading indicators.
Disable form buttons during submission to prevent duplicate actions and improve UX.
Always import useTransition from '@remix-run/react' inside Remix components.
Handle both submitting and loading states for complete user feedback.