react-compiler について
React Compilerを有効にしたReact 19以降のプロジェクト向けコーディングスキルです。不要な手動メモ化を避け、定められた例外では維持し、コンパイラー設定やlintの問題も監査します。
主な機能
- 01手動メモ化を原則として避ける
- 02定められた3つの例外ではメモ化を維持
- 03コンパイラーとlint設定の確認
- 04既存のメモ化使用状況の監査
- 05コンパイル対象外となるパターンの特定
活用シーン
- 01不要なラッパーのないReactコンポーネント作成
- 02コンパイラー有効環境でのメモ化レビュー
- 03監査前のコンパイラーとlint設定確認
- 04コンパイルを妨げるパターンの発見と修正
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ saschb2b/ skills --skill react-compilerインストール後、Claude Code で/react-compilerを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
CARD.manifest.jsonCARD.mdCARD.md.sigstoreCARD.svgpermissions.yamlreferences/exceptions.mdindex.mdlint-setup.md詳細
React Compiler
ルール
コンパイラーがメモ化します。あなたがする必要はありません。
コンパイラーを有効にした React 19 以降のコードベースでは、デフォルトで useMemo、useCallback、React.memo を追加しないでください。コンパイラーは、人が書くよりも細かい粒度でメモ化を処理するため、手動で追加しても、せいぜいノイズになるだけです。これは LLM が生成する React で最もよく見られる失敗パターンです。エージェントが学習した React のコードの大半はコンパイラー登場前のものなので、デフォルトの出力が手動メモ化に偏ります。
React を記述するときのデフォルトの動作
コンポーネントは簡潔に記述します。
function DashboardRow({ entity, onSelect }) {
const label = formatLabel(entity);
const total = entity.items.reduce((sum, i) => sum + i.value, 0);
return (
<Row onClick={() => onSelect(entity.id)}>
<Label>{label}</Label>
<Total>{total}</Total>
</Row>
);
}
次のようにはしません。
const DashboardRow = memo(({ entity, onSelect }) => {
const formatted = useMemo(() => ({ /* ... */ }), [entity]);
const handleClick = useCallback(() => onSelect(entity.id), [entity.id, onSelect]);
return /* ... */;
});
React のルールに従う入力であれば、コンパイラーは同等のものを最初の例のように生成します。2 つ目の例を手動で追加してもノイズになり、コンパイラーの解析を妨げる可能性があります。
手動メモ化が引き続き必要な 3 つの例外
次の場合に限り、手動の useMemo または useCallback を残します。
- React 以外のコンシューマーに対する参照同一性。
addEventListener、IntersectionObserver、独自の===チェックを行うサードパーティーライブラリーなど、React の外部で参照を保持するものに渡す値。 - コンパイラーが解析できない、レンダー以外の高コストな処理。 大きなデータの解析、大規模なインデックスの構築、負荷の高いライブラリーの呼び出しなどです。これらは残し、その理由を説明するコメントを追加します。
- 正確性のために安定させる必要がある Effect の依存関係。 ラップしないと依存関係によって毎回のレンダーで Effect が実行されてしまう場合は、残します。
この 3 つのケースに当てはまらないものはすべて削除します。
既存のコードベースでの監査ワークフロー
- コンパイラーが有効になっていることを確認します。
next.config(experimental.reactCompiler)、vite.configまたはbabel.config(babel-plugin-react-compiler)、あるいは Expo と TanStack Start のフレームワークのデフォルト設定を確認します。有効でない場合は、まず有効化を提案します。コンパイラーが無効なコードベースでは、メモ化を削除しないでください。 eslint-plugin-react-hooksが v6 以降であることを確認します。 コンパイラーのルールは、非推奨となったeslint-plugin-react-compilerから 2025 年後半に統合されました。- Lint ルールを
errorに引き上げます。recommendedではほとんどのルールがwarnに設定されているため、コンパイラーが問題を検出せずにスキップしても CI は失敗しません。厳格な設定については、lint-setup.md を参照してください。 - 手動メモ化を一掃します。 3 つの例外のいずれにも当てはまらない
useMemo、useCallback、React.memoを削除します。 - Lint を実行し、検出されないスキップを順次修正します。 検出されないスキップは連鎖します。上流のスキップを修正すると、下流に別の問題が見つかることがあります。最初の実行で件数を確認し、その後の実行で実態を把握します。
"use no memo"ディレクティブを追跡します。 それぞれがパフォーマンス上の大きな低下につながる可能性があり、背後には TODO があります。健全性の指標として、時間の経過に伴う件数を grep で確認します。
コンパイラーが暗黙に処理を中断する場合
5 つのパターンによって、周囲の関数がコンパイル対象から外れます。上記の Lint ルールを厳格に設定すれば、これらを検出できます。全リスト、コード例、修正方法については、exceptions.md を参照してください。
監査の出力形式
file: <path>
findings:
- removed: <useMemo | useCallback | memo> @ <line>, compiler handles
- kept: <useMemo | useCallback> @ <line>, reason: <ref-identity | expensive | effect-dep>
silent bails detected:
- <pattern> @ <line>: <one-line fix>
出典
The React Compiler at Eighteen Months に基づいています。関連する詳細については、exceptions.md と lint-setup.md を参照してください。