Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
davila7 avatar

React Ui Patterns

  • 507 installs
  • 30.1k repo stars
  • Updated August 4, 2026
  • davila7/claude-code-templates

react-ui-patterns is a Claude Code skill that generates consistent production-grade React component patterns for loading states, error handling, optimistic updates, and async data fetching for developers building modern

About

react-ui-patterns is a collection of reusable React component templates and UI patterns that developers and developers use to speed up frontend work. It gives you battle-tested starting points for common interface elements so you spend less time on boilerplate and more time on product logic. The skill works seamlessly with Claude Code, Cursor, and other agentic coding tools by providing clear, well-structured examples that agents can easily understand and extend. Whether you are building a SaaS dashboard, a marketing site, or an AI tool interface, these patterns help maintain consistency and quality without forcing you to reinvent common UI solutions every time.

  • Provides ready-to-use React UI component templates
  • Enforces consistent design patterns across your codebase
  • Accelerates frontend development with Claude Code and Cursor
  • Includes responsive and accessible component variants
  • Works with Tailwind, shadcn/ui, and modern React stacks

React Ui Patterns by the numbers

  • 507 all-time installs (skills.sh)
  • Ranked #619 of 2,245 Frontend Development skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/davila7/claude-code-templates --skill react-ui-patterns

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs507
repo stars30.1k
Last updatedAugust 4, 2026
Repositorydavila7/claude-code-templates

How do you handle loading and error states in React?

Generate consistent, production-grade React component patterns and UI implementations quickly.

Who is it for?

React developers implementing async data UIs who want consistent loading, error, and optimistic update patterns without reinventing state logic.

Skip if: Vue or Svelte projects, pure CSS layout work, or backend API design without React component implementation.

When should I use this skill?

User builds React UI components, handles async data fetching, or needs loading spinner, error boundary, or optimistic update patterns.

What you get

Production React components with loading, error, optimistic update, and progressive disclosure patterns implemented consistently.

  • React UI components
  • async state handlers
  • error display patterns

Files

SKILL.mdMarkdownGitHub ↗

React UI Patterns

Core Principles

1. Never show stale UI - Loading spinners only when actually loading 2. Always surface errors - Users must know when something fails 3. Optimistic updates - Make the UI feel instant 4. Progressive disclosure - Show content as it becomes available 5. Graceful degradation - Partial data is better than no data

Loading State Patterns

The Golden Rule

Show loading indicator ONLY when there's no data to display.

// CORRECT - Only show loading when no data exists
const { data, loading, error } = useGetItemsQuery();

if (error) return <ErrorState error={error} onRetry={refetch} />;
if (loading && !data) return <LoadingState />;
if (!data?.items.length) return <EmptyState />;

return <ItemList items={data.items} />;
// WRONG - Shows spinner even when we have cached data
if (loading) return <LoadingState />; // Flashes on refetch!

Loading State Decision Tree

Is there an error?
  → Yes: Show error state with retry option
  → No: Continue

Is it loading AND we have no data?
  → Yes: Show loading indicator (spinner/skeleton)
  → No: Continue

Do we have data?
  → Yes, with items: Show the data
  → Yes, but empty: Show empty state
  → No: Show loading (fallback)

Skeleton vs Spinner

Use Skeleton WhenUse Spinner When
Known content shapeUnknown content shape
List/card layoutsModal actions
Initial page loadButton submissions
Content placeholdersInline operations

Error Handling Patterns

The Error Handling Hierarchy

1. Inline error (field-level) → Form validation errors
2. Toast notification → Recoverable errors, user can retry
3. Error banner → Page-level errors, data still partially usable
4. Full error screen → Unrecoverable, needs user action

Always Show Errors

CRITICAL: Never swallow errors silently.

// CORRECT - Error always surfaced to user
const [createItem, { loading }] = useCreateItemMutation({
  onCompleted: () => {
    toast.success({ title: 'Item created' });
  },
  onError: (error) => {
    console.error('createItem failed:', error);
    toast.error({ title: 'Failed to create item' });
  },
});

// WRONG - Error silently caught, user has no idea
const [createItem] = useCreateItemMutation({
  onError: (error) => {
    console.error(error); // User sees nothing!
  },
});

Error State Component Pattern

interface ErrorStateProps {
  error: Error;
  onRetry?: () => void;
  title?: string;
}

const ErrorState = ({ error, onRetry, title }: ErrorStateProps) => (
  <div className="error-state">
    <Icon name="exclamation-circle" />
    <h3>{title ?? 'Something went wrong'}</h3>
    <p>{error.message}</p>
    {onRetry && (
      <Button onClick={onRetry}>Try Again</Button>
    )}
  </div>
);

Button State Patterns

Button Loading State

<Button
  onClick={handleSubmit}
  isLoading={isSubmitting}
  disabled={!isValid || isSubmitting}
>
  Submit
</Button>

Disable During Operations

CRITICAL: Always disable triggers during async operations.

// CORRECT - Button disabled while loading
<Button
  disabled={isSubmitting}
  isLoading={isSubmitting}
  onClick={handleSubmit}
>
  Submit
</Button>

// WRONG - User can tap multiple times
<Button onClick={handleSubmit}>
  {isSubmitting ? 'Submitting...' : 'Submit'}
</Button>

Empty States

Empty State Requirements

Every list/collection MUST have an empty state:

// WRONG - No empty state
return <FlatList data={items} />;

// CORRECT - Explicit empty state
return (
  <FlatList
    data={items}
    ListEmptyComponent={<EmptyState />}
  />
);

Contextual Empty States

// Search with no results
<EmptyState
  icon="search"
  title="No results found"
  description="Try different search terms"
/>

// List with no items yet
<EmptyState
  icon="plus-circle"
  title="No items yet"
  description="Create your first item"
  action={{ label: 'Create Item', onClick: handleCreate }}
/>

Form Submission Pattern

const MyForm = () => {
  const [submit, { loading }] = useSubmitMutation({
    onCompleted: handleSuccess,
    onError: handleError,
  });

  const handleSubmit = async () => {
    if (!isValid) {
      toast.error({ title: 'Please fix errors' });
      return;
    }
    await submit({ variables: { input: values } });
  };

  return (
    <form>
      <Input
        value={values.name}
        onChange={handleChange('name')}
        error={touched.name ? errors.name : undefined}
      />
      <Button
        type="submit"
        onClick={handleSubmit}
        disabled={!isValid || loading}
        isLoading={loading}
      >
        Submit
      </Button>
    </form>
  );
};

Anti-Patterns

Loading States

// WRONG - Spinner when data exists (causes flash)
if (loading) return <Spinner />;

// CORRECT - Only show loading without data
if (loading && !data) return <Spinner />;

Error Handling

// WRONG - Error swallowed
try {
  await mutation();
} catch (e) {
  console.log(e); // User has no idea!
}

// CORRECT - Error surfaced
onError: (error) => {
  console.error('operation failed:', error);
  toast.error({ title: 'Operation failed' });
}

Button States

// WRONG - Button not disabled during submission
<Button onClick={submit}>Submit</Button>

// CORRECT - Disabled and shows loading
<Button onClick={submit} disabled={loading} isLoading={loading}>
  Submit
</Button>

Checklist

Before completing any UI component:

UI States:

  • [ ] Error state handled and shown to user
  • [ ] Loading state shown only when no data exists
  • [ ] Empty state provided for collections
  • [ ] Buttons disabled during async operations
  • [ ] Buttons show loading indicator when appropriate

Data & Mutations:

  • [ ] Mutations have onError handler
  • [ ] All user actions have feedback (toast/visual)

Integration with Other Skills

  • graphql-schema: Use mutation patterns with proper error handling
  • testing-patterns: Test all UI states (loading, error, empty, success)
  • formik-patterns: Apply form submission patterns

Related skills

FAQ

When should React show a loading spinner?

react-ui-patterns follows the golden rule: show a loading indicator only when there is no data to display. If cached or partial data exists, render it immediately instead of flashing a spinner over stale UI.

Does react-ui-patterns cover optimistic updates?

Yes. react-ui-patterns includes optimistic update patterns, progressive disclosure as data arrives, graceful degradation with partial data, and explicit error surfacing so users always know when async operations fail.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.