mcpField
R
react-best-practices

react-best-practices

github.com/alleneubank開発503.2k 回インストール18 週間前に更新
リポジトリ

react-best-practices について

コーディングエージェント向けの React スキルで、コンポーネントロジック、Effect、ref、フック、コンポジションを扱います。外部システムとの同期と、レンダーやイベントハンドラーで処理すべきロジックを区別します。

主な機能

  1. 01Effect の判断ガイド
  2. 02ref の使用パターン
  3. 03カスタムフックの指針
  4. 04コンポジション重視のコンポーネント
  5. 05派生状態の扱い方

活用シーン

  1. 01Effect を使うべきかの判断
  2. 02ユーザー操作に伴う状態変更の処理
  3. 03再利用可能なコンポーネント群の構成

インストール

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

$npx skills add https://github.com/alleneubank/claude-code --skill react-best-practices

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

同梱ファイルreact-patterns.md

詳細

React のベストプラクティス

TypeScript と組み合わせる

React を使用する際は、このスキルと typescript-best-practices を常に一緒に読み込んでください。型を優先した開発、判別可能なユニオン、Zod による検証などの TypeScript のパターンは、React のコードにも適用されます。

基本原則:Effect は最後の手段です

Effect を使うと、React の外に出て、外部システムと同期できます。コンポーネントのロジックの大半で Effect を使うべきではありません。 Effect を書く前に、「Effect を使わずに実現する方法はないだろうか?」と考えてください。

判断フロー

  1. ユーザーの操作に応答する必要がありますか? イベントハンドラーを使います
  2. props/state から値を計算する必要がありますか? レンダリング中に計算します
  3. コストの高い計算結果をキャッシュする必要がありますか? useMemo を使います
  4. prop の変更時に state をリセットする必要がありますか? key prop を使います
  5. 外部システムと同期する必要がありますか? クリーンアップ関数を含む Effect を使います
  6. Effect 内でリアクティブではないコードが必要ですか? useEffectEvent を使います
  7. レンダリングを引き起こさない可変値が必要ですか? ref を使います

Effect を使う場合

外部システムとの同期:ブラウザー API(WebSocket、IntersectionObserver)、サードパーティ製の非 React ライブラリ、window/document のイベントリスナー、React 管理外の DOM 要素(動画、地図)。

Effect を使わない場合

  • 派生 state — レンダリング中に計算します
  • コストの高い計算 — useMemo を使います
  • prop の変更時の state のリセット — key prop を使います
  • ユーザーイベントへの応答 — イベントハンドラーを使います
  • state の変更を親に通知する — 同じイベントハンドラー内で両方を更新します
  • Effect の連鎖 — 派生 state を計算し、1 つのイベントハンドラー内で更新します

Refs

  • レンダリングに影響しない値(タイマー ID、DOM ノードへの参照)に使います
  • レンダリング中に ref.current を読み書きしないでください。イベントハンドラーと Effect 内でのみ操作します
  • 動的なリストには ref コールバックを使います(ループ内で useRef を使うのではなく)
  • useImperativeHandle を使って、親からアクセスできるものを制限します

カスタムフック

  • state ではなくロジックを共有します。呼び出しごとに独立した state インスタンスが作られます
  • 実際にほかのフックを呼び出す場合にのみ useXxx という名前を付けます。それ以外は通常の関数にします
  • ライフサイクルフック(useMount、useEffectOnce)は避けます。依存関係の不足をリンターが検出できるよう、useEffect を直接使います
  • 単一の具体的なユースケースに焦点を絞ります

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

  • 制御コンポーネント:親が state を管理します。非制御コンポーネント:コンポーネントが state を管理します
  • props のバケツリレーより、children を使ったコンポジションを優先します
  • 大きなコンポーネントツリーを切り替えるブール値の props(isEditing、isThread、hideAttachments)は、コンポジションに問題がある兆候と考えます。ユースケースごとに、コンポジションで構成した別々のコンポーネントを優先します
  • 複雑で再利用可能な UI には、多数の省略可能な props を持つ一枚岩のコンポーネントより、プロバイダーのスコープ内で state/アクションを管理する複合コンポーネントを優先します
  • 子孫コンポーネントが使用するローカルインターフェースを定義する場合は、真にグローバルな state だけでなく、スコープを限定したコンポーネント群にも Context を使います
  • UI のバリエーションには JSX を直接記述します。設定が実際のドメインデータでない限り、設定配列を使ったミニフレームワークは避けます
  • 兄弟コンポーネントや外部のコントロールから同じ state/アクションにアクセスする必要がある場合は、プロバイダーの境界を上位に移します
  • state の更新後に DOM を同期的に読み取る必要がある場合は、flushSync を使います

コード例と詳しいパターンについては、react-patterns.md を参照してください。

コメント