react について
このReactスキルは、React 19.2とReact Compiler 1.0を使う開発者向けのガイドです。コンパイラーを考慮したコンポーネントやフックの実装を中心に、作業内容別のリファレンスを提供します。
主な機能
- 01React Compilerを考慮した実装ガイド
- 02メモ化の判断指針
- 03純粋性とミューテーションの規則
- 04作業別に整理されたリファレンス
- 05React 19 APIとテストのガイド
活用シーン
- 01コンポーネントやフックの実装・レビュー
- 02コンパイラーとlintルールの設定
- 03手動メモ化を維持するかの判断
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pedronauck/ skills --skill reactインストール後、Claude Code で/reactを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/compiler-setup.mdcompiler.mdcomponents-and-types.mdeffects.mdreact19-apis.mdrules-of-react.mdstate.mdtesting.md詳細
React
React 19.2 と React Compiler 1.0(babel-plugin-react-compiler)を対象とし、eslint-plugin-react-hooks 7.1+ でリントします。変更する API または動作に対応するリファレンスを読みます。変更が関わる範囲に限って隣接するリファレンスを読み、すでに読んだ関連コンテキストは再利用します。
コンパイラーが最適化を担います
コンパイラーはビルド時に、すべてのコンポーネントに memo と同等の処理を適用し、コンポーネントとフック内の計算をメモ化します。手書きのフックよりも細かい粒度でメモ化できます。useMemo では構造上使えない早期リターンの後でもメモ化します。
その代わり、React のルールはスタイル上の助言ではなく、ビルド時の契約になりました。コンポーネントがルールに違反すると、コンパイラーは処理を中断します。何も知らせずにそのコンポーネントの最適化をスキップして、次へ進みます。ビルドもテストも成功したまま、コンポーネントは最適化されないままです。コンパイラーが処理を中断せずに済むコードを書きましょう。
これによって、コンパイラー導入前の習慣を逆転させる2つの結果が生じます。
- 安価な値に対して反射的に
useMemo/useCallbackを使うのは、今や不要なノイズです。また、依存配列が不完全な場合、まったくメモ化しないよりも悪い結果になります。手動のメモ化を照合できないコンポーネントは、コンパイラーが最適化しないためです。 - ルール違反はエラーになるのではなく、最適化がひそかに行われなくなるため、リントルールだけがアプリの最適化漏れを防ぎます。コンパイラーを有効にする前に、リントルールを有効にしてください。
まずメモ化が必要か判断する
| 状況 | 対応 |
|---|---|
| 新しい値またはコールバックがレンダー/JSX でのみ使われる | そのまま記述します。コンパイラーがメモ化します |
値が useEffect(または別のフック)の依存配列に入り、同一性を維持する必要がある | useMemo/useCallback を維持します。react.dev が明示している回避策です |
値がコンパイル対象外の利用側(バニラのライブラリーインスタンス、addEventListener、未コンパイルのパッケージ)に渡る | 手動のメモ化を維持します |
| 何らかの理由で手動のメモ化を維持する場合 | 依存配列をすべて網羅させます。そうしないとコンポーネントは処理を中断します |
| 既存コードで機能しているメモ化 | そのままにします。削除するとコンパイル結果が変わるため、変更する前にテストしてください |
| 同じ高コストな呼び出しが複数のコンポーネントで繰り返される | コンパイラーのメモ化はコンポーネントごとで、共有されません。モジュールレベルのキャッシュまたはデータレイヤーに移します |
| 通常のモジュールレベルのユーティリティ内にある高コストな処理 | まったくメモ化されません。コンパイラーが対象とするのはコンポーネントとフックのみです |
カスタムの areEqual 比較関数を使う memo() | 維持します。コンパイラーに同等の機能はありません |
完了条件: このタスクで追加または変更した各メモ化が上記のいずれかの行に該当し、コンパイラーがすでに担う処理をフックの追加で実現していないこと。
分岐
| 次の作業を行う場合 | リファレンス |
|---|---|
| コンポーネントまたはフック本体を記述またはレビューする(純粋性、変更、ref、グローバル変数) | references/rules-of-react.md |
useMemo/useCallback/memo を削除、維持、検討する場合、またはコンパイラーがコンポーネントをスキップした場合 | references/compiler.md |
| コンパイラーやリントプリセットのインストールまたは設定、あるいは段階的な導入を行う場合 | references/compiler-setup.md |
useEffect を使う場合、または state の導出/同期を行う場合 | references/effects.md |
| コンポーネント、合成、props、TypeScript の型を設計する場合 | references/components-and-types.md |
| state の配置場所を決める場合、コンテキストや外部ストアを接続する場合 | references/state.md |
use()、Actions、useOptimistic、<Activity>、メタデータ、その他の React 19 API を使う場合 | references/react19-apis.md |
| コンポーネント/フックのテストを記述または修正する場合 | references/testing.md |
変更する動作に関係する技術ルールを適用してください。
Tripwires
純粋性 — レンダリングでは props、state、context のみから計算します。Math.random()、Date.now()、new Date()、crypto.randomUUID()、performance.now() は、state 初期化関数、イベントハンドラー、またはエフェクト内で使用します。
ミューテーション — props、state、フックの引数、フックの戻り値、すでに JSX に渡した値は読み取り専用です。変更する前にコピーしてください(setItems([...items].sort()))。このレンダリング内で作成され、外部に渡されない値は自由に変更できます。
再代入 — 分割代入した prop は読み取り専用として扱います。分割代入時に名前を変更し({ value: valueFromProps })、新しい const を導出してください。
Refs — ref.current の読み取りと書き込みは、エフェクトとイベントハンドラー内で行います。レンダリング中に許可される操作は、次のような一度だけの遅延初期化です:if (ref.current === null) ref.current = …。
グローバル — モジュールスコープには定数を置き、レンダリングごとの値は useState/useContext に置き、外部への書き込みはエフェクト内で行います。レンダリング中に触れるカウンター、配列、場当たり的なキャッシュは Fast Refresh を壊し、コンパイルもできなくなります。
コンポーネントは静的です — コンポーネントとフックはモジュールスコープで宣言します。別のコンポーネント内で定義したり(またはファクトリーから返したり)すると、レンダリングごとに新しい型が作られ、state がリセットされ、DOM が破棄されます。
エフェクト — エフェクトは React の外部にあるものと同期するために使います。state の導出やコピーを目的としてエフェクト内で同期的に setState を呼び出すと、エラーレベルの lint 違反になります。代わりにレンダリング中に計算してください。
エラー — 子のレンダリングエラーは Error Boundary で捕捉します。JSX の周囲で try/catch を使って捕捉することはできません。
Refs は props です — 19 では forwardRef は非推奨です。props の型で ref を受け取ってください。同様に、<Context.Provider> ではなく <Context value={…}> を使います。
エスケープハッチ — "use no memo" は、理由と削除計画を文書で示して使う二分探索用のツールであり、修正策ではありません。
関連するスキル
TanStack Query、Router、Form には tanstack を使用します。@xstate/store には xstate-store を使用します。コンポーネントのプリミティブと CVA バリアントには shadcn を使用します。スタイリングには tailwindcss を使用します。references/testing.md の範囲を超えるランナー設定には vitest を使用します。