スキル一覧に戻る
aj-geddes

react-component-architecture

by aj-geddes

A curated collection of useful AI prompts for various tasks and use cases

40🍴 4📅 2026年1月23日
GitHubで見るManusで実行

SKILL.md


name: react-component-architecture description: Design scalable React components using functional components, hooks, composition patterns, and TypeScript. Use when building reusable component libraries and maintainable UI systems.

React Component Architecture

Overview

Build scalable, maintainable React components using modern patterns including functional components, hooks, composition, and TypeScript for type safety.

When to Use

  • Component library design
  • Large-scale React applications
  • Reusable UI patterns
  • Custom hooks development
  • Performance optimization

Implementation Examples

1. Functional Component with Hooks

// Button.tsx
import React, { useState, useCallback } from 'react';

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

export const Button: React.FC<ButtonProps> = ({
  variant = 'primary',
  size = 'md',
  disabled = false,
  onClick,
  children
}) => {
  const variantStyles = {
    primary: 'bg-blue-500 hover:bg-blue-600',
    secondary: 'bg-gray-500 hover:bg-gray-600',
    danger: 'bg-red-500 hover:bg-red-600'
  };

  const sizeStyles = {
    sm: 'px-2 py-1 text-sm',
    md: 'px-4 py-2 text-base',
    lg: 'px-6 py-3 text-lg'
  };

  return (
    <button
      className={`${variantStyles[variant]} ${sizeStyles[size]} text-white rounded disabled:opacity-50`}
      disabled={disabled}
      onClick={onClick}
    >
      {children}
    </button>
  );
};

2. Custom Hooks Pattern

// useFormInput.ts
import { useState, useCallback } from 'react';

interface UseFormInputOptions {
  initialValue?: string;
  validator?: (value: string) => string | null;
}

export const useFormInput = (options: UseFormInputOptions = {}) => {
  const [value, setValue] = useState(options.initialValue || '');
  const [error, setError] = useState<string | null>(null);

  const validate = useCallback(() => {
    if (options.validator) {
      const validationError = options.validator(value);
      setError(validationError);
      return !validationError;
    }
    return true;
  }, [value, options.validator]);

  const reset = useCallback(() => {
    setValue(options.initialValue || '');
    setError(null);
  }, [options.initialValue]);

  return {
    value,
    setValue,
    error,
    validate,
    reset,
    bind: {
      value,
      onChange: (e: React.ChangeEvent<HTMLInputElement>) => setValue(e.target.value)
    }
  };
};

// Usage
const MyForm: React.FC = () => {
  const email = useFormInput({
    validator: (v) => !v.includes('@') ? 'Invalid email' : null
  });

  return (
    <div>
      <input {...email.bind} />
      {email.error && <span className="text-red-500">{email.error}</span>}
    </div>
  );
};

3. Composition Pattern

// Card.tsx
interface CardProps {
  children: React.ReactNode;
  className?: string;
}

const Card: React.FC<CardProps> = ({ children, className = '' }) => (
  <div className={`border rounded p-4 ${className}`}>{children}</div>
);

const CardHeader: React.FC<CardProps> = ({ children }) => (
  <div className="border-b pb-2 mb-3 font-bold">{children}</div>
);

const CardBody: React.FC<CardProps> = ({ children }) => (
  <div className="py-2">{children}</div>
);

const CardFooter: React.FC<CardProps> = ({ children }) => (
  <div className="border-t pt-2 mt-3">{children}</div>
);

// Compound component
export { Card };
Card.Header = CardHeader;
Card.Body = CardBody;
Card.Footer = CardFooter;

// Usage
<Card>
  <Card.Header>Title</Card.Header>
  <Card.Body>Content</Card.Body>
  <Card.Footer>Actions</Card.Footer>
</Card>

4. Higher-Order Component (HOC)

// withLoader.tsx
interface WithLoaderProps {
  isLoading: boolean;
  error?: Error | null;
}

function withLoader<P extends object>(
  Component: React.ComponentType<P>
): React.FC<P & WithLoaderProps> {
  return ({ isLoading, error, ...props }: P & WithLoaderProps) => {
    if (isLoading) return <div>Loading...</div>;
    if (error) return <div className="text-red-500">{error.message}</div>;
    return <Component {...(props as P)} />;
  };
}

// Usage
const UserList: React.FC<{ users: User[] }> = ({ users }) => (
  <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>
);

export const LoadingUserList = withLoader(UserList);

5. Render Props Pattern

// DataFetcher.tsx
interface DataFetcherProps<T> {
  url: string;
  children: (data: T | null, loading: boolean, error: Error | null) => React.ReactNode;
}

export const DataFetcher = <T,>({ url, children }: DataFetcherProps<T>) => {
  const [data, setData] = React.useState<T | null>(null);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState<Error | null>(null);

  React.useEffect(() => {
    fetch(url)
      .then(r => r.json())
      .then(setData)
      .catch(setError)
      .finally(() => setLoading(false));
  }, [url]);

  return <>{children(data, loading, error)}</>;
};

// Usage
<DataFetcher<User[]> url="/api/users">
  {(users, loading, error) => (
    <>{loading ? <p>Loading...</p> : users?.map(u => <p key={u.id}>{u.name}</p>)}</>
  )}
</DataFetcher>

Best Practices

  • Use TypeScript for type safety
  • Implement proper prop validation
  • Keep components focused and single-purpose
  • Leverage hooks for state and side effects
  • Use composition over inheritance
  • Memoize expensive computations
  • Extract custom hooks for reusable logic

Resources

スコア

総合スコア

60/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です