react-best-practices について
コーディングエージェント向けの React スキルで、コンポーネントロジック、Effect、ref、フック、コンポジションを扱います。外部システムとの同期と、レンダーやイベントハンドラーで処理すべきロジックを区別します。
主な機能
- 01Effect の判断ガイド
- 02ref の使用パターン
- 03カスタムフックの指針
- 04コンポジション重視のコンポーネント
- 05派生状態の扱い方
活用シーン
- 01Effect を使うべきかの判断
- 02ユーザー操作に伴う状態変更の処理
- 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 を使わずに実現する方法はないだろうか?」と考えてください。
判断フロー
- ユーザーの操作に応答する必要がありますか? イベントハンドラーを使います
- props/state から値を計算する必要がありますか? レンダリング中に計算します
- コストの高い計算結果をキャッシュする必要がありますか?
useMemoを使います - prop の変更時に state をリセットする必要がありますか?
keyprop を使います - 外部システムと同期する必要がありますか? クリーンアップ関数を含む Effect を使います
- Effect 内でリアクティブではないコードが必要ですか?
useEffectEventを使います - レンダリングを引き起こさない可変値が必要ですか? ref を使います
Effect を使う場合
外部システムとの同期:ブラウザー API(WebSocket、IntersectionObserver)、サードパーティ製の非 React ライブラリ、window/document のイベントリスナー、React 管理外の DOM 要素(動画、地図)。
Effect を使わない場合
- 派生 state — レンダリング中に計算します
- コストの高い計算 —
useMemoを使います - prop の変更時の state のリセット —
keyprop を使います - ユーザーイベントへの応答 — イベントハンドラーを使います
- 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 を参照してください。
コメント
Markdown 対応