mcpField
R
react

react

github.com/claude-dev-suite開発4643 回インストール4 日前に更新
リポジトリ

react について

react は、React アプリケーションを開発する人向けのリファレンススキルです。コンポーネントやフックの基本、パフォーマンス、アクセシビリティ、セキュリティ、テスト、トラブルシューティングを扱います。

主な機能

  1. 01関数コンポーネントと Props のパターン
  2. 02主要な React フック
  3. 03状態管理とコンポジションの指針
  4. 04パフォーマンス最適化
  5. 05アクセシビリティとセキュリティ対策
  6. 06テストとトラブルシューティング

活用シーン

  1. 01再利用可能な React コンポーネントの構成
  2. 02ローカル状態と共有状態の管理
  3. 03フックやレンダリング問題の診断
  4. 04アクセシビリティと本番運用準備の確認

MCP 対応

README では、technology `react` を指定して包括的な React ドキュメントを取得する mcp__documentation__fetch_docs を案内しています。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/claude-dev-suite/claude-dev-suite --skill react

インストール後、Claude Code で/reactを入力して読み込まれたか確認します。

同梱ファイルquick-ref/component-patterns.mdquick-ref/hooks-cheatsheet.md

詳細

React コア知識

深い知識:フック、コンポーネント、React のパターンに関する包括的なドキュメントを参照するには、technology: react を指定して mcp__documentation__fetch_docs を使用してください。

コンポーネントのパターン

関数コンポーネント(推奨)
function UserCard({ name, email }: UserCardProps) {
  return (
    <div className="card">
      <h2>{name}</h2>
      <p>{email}</p>
    </div>
  );
}
Props の型指定
interface Props {
  title: string;
  count?: number;
  children: React.ReactNode;
  onClick: (id: string) => void;
}

基本的なフック

フック目的
useStateローカル状態
useEffect副作用、サブスクリプション
useContextコンテキスト値へのアクセス
useRefDOM の参照、可変値
useMemoコストの高い計算をメモ化
useCallback関数をメモ化
useReducer複雑な状態ロジック

主なパターン

  • 継承よりコンポジション
  • 共有状態には状態を上位に持ち上げる
  • Props のバケツリレー → Context または状態管理ライブラリを使用
  • 制御コンポーネントと非制御コンポーネントの入力

パフォーマンス

  • コストの高い純粋コンポーネントには React.memo() を使用します
  • 必要な場合にのみ useMemo/useCallback でメモ化します
  • リストでは key プロパティを正しく使用します
  • React.lazy() と Suspense で遅延読み込みします

本番環境への対応

セキュリティのベストプラクティス
// NEVER use dangerouslySetInnerHTML with user input
// BAD
<div dangerouslySetInnerHTML={{ __html: userInput }} />

// GOOD - Sanitize with DOMPurify
import DOMPurify from 'dompurify';
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userInput) }} />

// Avoid exposing sensitive data in client-side state
// BAD
const [apiKey, setApiKey] = useState(process.env.API_KEY);

// GOOD - API keys should stay server-side
// Use API routes or server actions instead

// Validate all external URLs
const isValidUrl = (url: string) => {
  try {
    const parsed = new URL(url);
    return ['http:', 'https:'].includes(parsed.protocol);
  } catch {
    return false;
  }
};
エラーバウンダリ
import { ErrorBoundary } from 'react-error-boundary';

function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
  return (
    <div role="alert">
      <p>Something went wrong:</p>
      <pre>{error.message}</pre>
      <button onClick={resetErrorBoundary}>Try again</button>
    </div>
  );
}

// Usage
<ErrorBoundary
  FallbackComponent={ErrorFallback}
  onReset={() => window.location.reload()}
  onError={(error, info) => {
    // Log to error reporting service
    logErrorToService(error, info);
  }}
>
  <App />
</ErrorBoundary>
パフォーマンスの最適化
// Code splitting with lazy loading
const Dashboard = lazy(() => import('./Dashboard'));

function App() {
  return (
    <Suspense fallback={<Skeleton />}>
      <Dashboard />
    </Suspense>
  );
}

// Memoization - use sparingly, only for expensive components
const ExpensiveList = memo(function ExpensiveList({ items }: Props) {
  return items.map(item => <ExpensiveItem key={item.id} {...item} />);
});

// Virtualization for large lists
import { FixedSizeList } from 'react-window';

function VirtualList({ items }: { items: Item[] }) {
  return (
    <FixedSizeList
      height={400}
      itemCount={items.length}
      itemSize={50}
      width="100%"
    >
      {({ index, style }) => (
        <div style={style}>{items[index].name}</div>
      )}
    </FixedSizeList>
  );
}
アクセシビリティ(a11y)
// Use semantic HTML
<button onClick={handleClick}>Submit</button>  // NOT <div onClick>

// ARIA labels for icons/images
<button aria-label="Close dialog" onClick={onClose}>
  <XIcon />
</button>

// Focus management
const dialogRef = useRef<HTMLDivElement>(null);
useEffect(() => {
  dialogRef.current?.focus();
}, [isOpen]);

// Keyboard navigation
const handleKeyDown = (e: KeyboardEvent) => {
  if (e.key === 'Escape') onClose();
  if (e.key === 'Tab') trapFocus(e);
};
テストのセットアップ
// Component testing with Testing Library
import { render, screen, userEvent } from '@testing-library/react';

test('submits form with user data', async () => {
  const onSubmit = vi.fn();
  render(<Form onSubmit={onSubmit} />);

  await userEvent.type(screen.getByLabelText(/email/i), '[email protected]');
  await userEvent.click(screen.getByRole('button', { name: /submit/i }));

  expect(onSubmit).toHaveBeenCalledWith({ email: '[email protected]' });
});
モニタリング指標
指標アラートのしきい値
最大コンテンツ描画時間(LCP)> 2.5s
初回入力遅延(FID)> 100ms
累積レイアウトシフト(CLS)> 0.1
JavaScript バンドルサイズ> 200KB(gzip 圧縮後)
コンポーネントのレンダリング時間> 16ms
ビルドとバンドルの最適化
// vite.config.ts
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['react', 'react-dom'],
          ui: ['@radix-ui/react-dialog', '@radix-ui/react-dropdown'],
        },
      },
    },
    sourcemap: true,  // For error tracking in production
  },
});
チェックリスト
  • 重要なセクションをエラーバウンダリでラップする
  • クライアントの状態に機密データを含めない
  • HTML の描画には必ず DOMPurify を使用する
  • ルート単位のコード分割に遅延読み込みを使用する
  • 大規模なリスト(>100 項目)には仮想化を使用する
  • セマンティック HTML と ARIA ラベルを使用する
  • キーボードナビゲーションをサポートする
  • Core Web Vitals をモニタリングする
  • バンドルサイズを最適化する(<200KB gzip)
  • 本番環境のデバッグ用にソースマップを用意する
  • エラー報告サービスを統合する

このスキルを使用しない場合

  • React 19 固有の機能(Actions、useActionState、use())— 代わりに react-19 スキルを使用してください
  • 高度なパフォーマンス最適化 — 代わりに react-performance スキルを使用してください
  • フォーム処理のパターン — 代わりに react-forms または react-hook-form スキルを使用してください
  • ルーティング — 代わりに react-router スキルを使用してください
  • テスト — 代わりに react-testing スキルを使用してください
  • コンポーネント設計のパターン — 代わりに react-patterns スキルを使用してください

アンチパターン

アンチパターン問題解決策
状態を直接変更する再レンダリングが発生しない新しいオブジェクト/配列を使って setState を呼び出す
依存配列がない古いクロージャ、メモリリークすべての依存関係を含めるか、ESLint を使用する
派生状態に useEffect を使う不要な再レンダリング描画中に計算するか、useMemo を使用する
Props を深くバケツリレーする保守が難しいContext または状態管理ライブラリを使用する
JSX 内にオブジェクト/配列を直接記述するメモ化が機能しなくなる定数に切り出すか、useMemo を使用する
レンダリング時に新しい関数を作成する子コンポーネントが不必要に再レンダリングされるuseCallback を使用する
useEffect のクリーンアップを忘れるメモリリーククリーンアップ関数を返す
インデックスを key として使用する不適切な再レンダリング安定した一意の ID を使用する

トラブルシューティング

問題考えられる原因対処法
コンポーネントが再レンダリングされない状態の変更新しい参照を使って setState を呼び出す
useEffect で無限ループが発生する依存関係がない、または誤っている依存関係を追加するか、関数型更新を使用する
「Cannot read property of undefined」非同期データが読み込まれていないnull チェックまたは読み込み状態を追加する
メモリリークの警告が出るクリーンアップがないuseEffect からクリーンアップ関数を返す
子要素が更新されないインデックスを key として使用している安定した一意の ID を使用する
ハンドラーが実行されないイベント伝播が停止されているstopPropagation() の呼び出しを確認する
コールバック内の状態が古い古い状態を保持したクロージャ関数型 setState を使用する

Reference Documentation

コメント