React Ui Patterns

davila7/claude-code-templates/cli-tool/components/skills/development/react-ui-patterns

作者 davila78da17d671b6f无许可证32K 个星标收录于 2026年10月8日更新于 2026年10月8日仓库今天更新

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

AI 生成的概览

提供 React UI 模式指南,涵盖加载状态、错误处理、空状态和表单提交。

功能
该技能为构建 React UI 组件提供参考指南和代码示例,统一处理加载、错误、空状态和按钮状态。内容包括何时使用加载指示器与骨架屏的决策树、错误处理层级,以及暴露错误和在异步操作期间禁用按钮的模式。它产出的是指导性内容和示例片段,而非可运行代码。
适用场景
适用于在 React 应用中构建 UI 组件、处理异步数据获取或管理 UI 状态时。也适合在审查组件是否缺少错误、加载或空状态时使用。
运行要求
无需脚本或工具,仅为说明性内容。示例涉及 React、TypeScript 和 GraphQL 风格的钩子,但阅读指南不需要安装任何包或提供凭据。

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 existsconst { 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} />;
typescript
// WRONG - Shows spinner even when we have cached dataif (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 errors2. Toast notification → Recoverable errors, user can retry3. Error banner → Page-level errors, data still partially usable4. Full error screen → Unrecoverable, needs user action

Always Show Errors

CRITICAL: Never swallow errors silently.

typescript
// CORRECT - Error always surfaced to userconst [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 ideaconst [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) => (  <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

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

Disable During Operations

CRITICAL: Always disable triggers during async operations.

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

tsx
// WRONG - No empty statereturn <FlatList data={items} />;
// CORRECT - Explicit empty statereturn (  <FlatList    data={items}    ListEmptyComponent={<EmptyState />}  />);

Contextual Empty States

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

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

typescript
// WRONG - Spinner when data exists (causes flash)if (loading) return <Spinner />;
// CORRECT - Only show loading without dataif (loading && !data) return <Spinner />;

Error Handling

typescript
// WRONG - Error swallowedtry {  await mutation();} catch (e) {  console.log(e); // User has no idea!}
// CORRECT - Error surfacedonError: (error) => {  console.error('operation failed:', error);  toast.error({ title: 'Operation failed' });}

Button States

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

来源与署名

来源:davila7/claude-code-templates位于cli-tool/components/skills/development/react-ui-patterns提交8da17d6

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架

React Ui Patterns · cli-tool/components/skills/development/react-ui-patterns 智能体技能 | SourceWeft