home / skills / aidotnet / moyucode / react-component

react-component skill

/skills/community/react-component

This skill generates modern React components with TypeScript, hooks, accessibility best practices, and a context provider pattern for state management.

npx playbooks add skill aidotnet/moyucode --skill react-component

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
4.3 KB
---
name: react-component
description: 生成React组件,包含TypeScript、hooks、状态管理和无障碍最佳实践。支持函数组件、自定义hooks和Context Provider。
metadata:
  short-description: 生成TypeScript React组件
---

# React Component Skill

## Description
Generate React components with TypeScript, hooks, and accessibility best practices.

## Trigger
- `/react` command
- User requests React component
- User needs React hooks

## Prompt

You are a React expert that creates modern, accessible components.

### Functional Component with Props

```tsx
import { FC, memo } from 'react';

interface ButtonProps {
  variant?: 'primary' | 'secondary' | 'danger';
  size?: 'sm' | 'md' | 'lg';
  disabled?: boolean;
  loading?: boolean;
  onClick?: () => void;
  children: React.ReactNode;
}

export const Button: FC<ButtonProps> = memo(({
  variant = 'primary',
  size = 'md',
  disabled = false,
  loading = false,
  onClick,
  children,
}) => {
  const baseStyles = 'inline-flex items-center justify-center font-medium rounded-lg transition-colors';
  
  const variants = {
    primary: 'bg-blue-600 text-white hover:bg-blue-700 disabled:bg-blue-300',
    secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300 disabled:bg-gray-100',
    danger: 'bg-red-600 text-white hover:bg-red-700 disabled:bg-red-300',
  };
  
  const sizes = {
    sm: 'px-3 py-1.5 text-sm',
    md: 'px-4 py-2 text-base',
    lg: 'px-6 py-3 text-lg',
  };

  return (
    <button
      type="button"
      className={`${baseStyles} ${variants[variant]} ${sizes[size]}`}
      disabled={disabled || loading}
      onClick={onClick}
      aria-busy={loading}
    >
      {loading && (
        <svg className="animate-spin -ml-1 mr-2 h-4 w-4" fill="none" viewBox="0 0 24 24">
          <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
          <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
        </svg>
      )}
      {children}
    </button>
  );
});

Button.displayName = 'Button';
```

### Custom Hook

```tsx
import { useState, useEffect, useCallback } from 'react';

interface UseFetchResult<T> {
  data: T | null;
  loading: boolean;
  error: Error | null;
  refetch: () => void;
}

export function useFetch<T>(url: string): UseFetchResult<T> {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  const fetchData = useCallback(async () => {
    setLoading(true);
    setError(null);
    
    try {
      const response = await fetch(url);
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      const json = await response.json();
      setData(json);
    } catch (e) {
      setError(e instanceof Error ? e : new Error('Unknown error'));
    } finally {
      setLoading(false);
    }
  }, [url]);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

  return { data, loading, error, refetch: fetchData };
}
```

### Context Provider

```tsx
import { createContext, useContext, useState, ReactNode } from 'react';

interface User {
  id: string;
  name: string;
  email: string;
}

interface AuthContextType {
  user: User | null;
  login: (email: string, password: string) => Promise<void>;
  logout: () => void;
  isAuthenticated: boolean;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

export function AuthProvider({ children }: { children: ReactNode }) {
  const [user, setUser] = useState<User | null>(null);

  const login = async (email: string, password: string) => {
    const response = await fetch('/api/auth/login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email, password }),
    });
    const data = await response.json();
    setUser(data.user);
  };

  const logout = () => setUser(null);

  return (
    <AuthContext.Provider value={{ user, login, logout, isAuthenticated: !!user }}>
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  const context = useContext(AuthContext);
  if (!context) throw new Error('useAuth must be used within AuthProvider');
  return context;
}
```

## Tags
`react`, `typescript`, `components`, `hooks`, `frontend`

## Compatibility
- Codex: ✅
- Claude Code: ✅

Overview

This skill generates production-ready React components in TypeScript with hooks, state management, and accessibility best practices. It supports function components, custom hooks, and Context Providers, producing small, composable building blocks you can drop into modern React apps. The output follows common patterns like memoization, typed props, ARIA attributes, and clear separation of concerns.

How this skill works

Given a request for a component, the skill returns a TypeScript function component with typed props, sensible defaults, and optional memoization. For data needs it can generate custom hooks that handle fetching, loading, error states, and refetching. For app-wide state it can scaffold a Context Provider and a typed useContext hook that enforces correct usage and simple auth patterns.

When to use it

  • You need a typed, accessible UI component (buttons, inputs, modals) ready for Tailwind or CSS modules.
  • You want a custom hook for data fetching with loading/error/refetch handling.
  • You need a lightweight Context Provider for auth or domain state with a typed consumer hook.
  • You want consistent patterns: memoized components, ARIA attributes, and clear prop defaults.
  • You are migrating JS components to TypeScript and need examples of typed props and hooks.

Best practices

  • Export components as named, memoized functions and set displayName for easier debugging.
  • Keep hooks side-effect focused: return stable callbacks, expose refetch methods, and handle cancellation if necessary.
  • Type context values strictly and throw when useContext is used outside the Provider.
  • Add ARIA attributes for dynamic states (aria-busy, aria-disabled) and provide visible focus styles.
  • Prefer small focused components and lift state to Context or hooks when shared across the tree.

Example use cases

  • Create a reusable Button component with loading spinner and variant/size props for a design system.
  • Generate a useFetch<T> hook to encapsulate API calls and reuse across pages.
  • Scaffold an AuthProvider that manages user state, login/logout, and a useAuth hook for consumers.
  • Build an accessible modal or form input with proper ARIA attributes and keyboard handling.
  • Provide TypeScript examples to accelerate migrating a legacy codebase to typed React.

FAQ

Will generated components include styling?

Yes—examples include utility-class friendly structure (Tailwind) and clear className slots; you can easily adapt to CSS modules or styled-components.

How are errors handled in hooks?

Hooks return an error object alongside data and loading, and provide a refetch callback. You can extend them to support retries or cancellation.