🎯

react-ui-patterns

🎯Skill

from liuchiawei/agent-skills

VibeIndex|
What it does

Provides reusable React UI patterns for handling loading states, errors, and async data with best practices and clean component logic.

πŸ“¦

Part of

liuchiawei/agent-skills(24 items)

react-ui-patterns

Installation

πŸ“‹ No install commands found in docs. Showing default command. Check GitHub for actual instructions.
Quick InstallInstall with npx
npx skills add liuchiawei/agent-skills --skill react-ui-patterns
1Installs
-
AddedFeb 4, 2026

Skill Details

SKILL.md

Modern React UI patterns for loading states, error handling, and data fetching. Use when building UI components, handling async data, or managing UI states.

Overview

# 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.

```typescript

// CORRECT - Only show loading when no data exists

const { data, loading, error } = useGetItemsQuery();

if (error) return ;

if (loading && !data) return ;

if (!data?.items.length) return ;

return ;

```

```typescript

// WRONG - Shows spinner even when we have cached data

if (loading) return ; // 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 When | Use Spinner When |

|-------------------|------------------|

| Known content shape | Unknown content shape |

| List/card layouts | Modal actions |

| Initial page load | Button submissions |

| Content placeholders | Inline 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.

```typescript

// 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

```typescript

interface ErrorStateProps {

error: Error;

onRetry?: () => void;

title?: string;

}

const ErrorState = ({ error, onRetry, title }: ErrorStateProps) => (

{title ?? 'Something went wrong'}

{error.message}

{onRetry && (

)}

);

```

Button State Patterns

Button Loading State

```tsx

onClick={handleSubmit}

isLoading={isSubmitting}

disabled={!isValid || isSubmitting}

>

Submit

```

Disable During Operations

CRITICAL: Always disable triggers during async operations.

```tsx

// CORRECT - Button disabled while loading

disabled={isSubmitting}

isLoading={isSubmitting}

onClick={handleSubmit}

>

Submit

// WRONG - User can tap multiple times

```

Empty States

Empty State Requirements

Every list/collection MUST have an empty state:

```tsx

// WRONG - No empty state

return ;

// CORRECT - Explicit empty state

return (

data={items}

ListEmptyComponent={}

/>

);

```

Contextual Empty States

```tsx

// Search with no results

icon="search"

title="No results found"

description="Try different search terms"

/>

// List with no items yet

icon="plus-circle"

title="No items yet"

description="Create your first item"

action={{ label: 'Create Item', onClick: handleCreate }}

/>

```

Form Submission Pattern

```tsx

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 (

value={values.name}

onChange={handleChange('name')}

error={touched.name ? errors.name : undefined}

/>

type="submit"

onClick={handleSubmit}

disabled={!isValid || loading}

isLoading={loading}

>

Submit

);

};

```

Anti-Patterns

Loading States

```typescript

// WRONG - Spinner when data exists (causes flash)

if (loading) return ;

// CORRECT - Only show loading without data

if (loading && !data) return ;

```

Error Handling

```typescript

// 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

```typescript

// WRONG - Button not disabled during submission

// CORRECT - Disabled and shows loading

```

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

More from this repository10

🎯
next-intl-app-router🎯Skill

Configures Next.js App Router internationalization with next-intl, enabling locale-based routing and translation management across multilingual projects.

🎯
code-refactoring-tech-debt🎯Skill

Refactors and improves code quality by identifying technical debt, suggesting optimizations, and generating cleaner, more efficient code implementations.

🎯
copywriting🎯Skill

Generates clear, compelling marketing copy that aligns with audience needs, business goals, and conversion best practices without fabricating claims.

🎯
frontend-patterns🎯Skill

I apologize, but I cannot generate a description without seeing the actual content or details of the "frontend-patterns" skill from the repository. Could you provide more context about what this sp...

🎯
web-design-guidelines🎯Skill

I apologize, but I cannot generate a description without seeing the actual content or context of the "web-design-guidelines" skill from the repository. Could you provide me with more details about ...

🎯
page-cro🎯Skill

Optimizes individual web pages for higher conversion rates by diagnosing performance issues and providing targeted, evidence-based recommendations.

🎯
clean-code🎯Skill

Enforces pragmatic coding standards by ensuring concise, direct code with clear responsibilities, minimal complexity, and no unnecessary abstractions.

🎯
ui-ux-pro-max🎯Skill

I apologize, but I cannot generate a description without seeing the actual content or details of the "ui-ux-pro-max" skill from the repository. Could you provide more context or information about w...

🎯
tailwind-patterns🎯Skill

Generates responsive and semantic CSS configurations using Tailwind CSS v4's native, CSS-first design token architecture and container query patterns.

🎯
error-diagnostics-smart-debug🎯Skill

I apologize, but I cannot generate a description without seeing the actual content or context of the "error-diagnostics-smart-debug" skill from the repository. Could you provide more details about ...