React Compiler (React 19)で不要になるメモ化コードと移行手順
React Frontend Performance JavaScript
結論
React Compilerにより useMemo / useCallback の手動記述は不要になり、自動最適化されます。
// React 19公式仕様:React Compiler 導入後のコンポーネント(手動メモ化フック一切不要)
export function ComponentList({ items, filterText }) {
// ⭕ useCallback や useMemo を一切書かなくても、ビルド時に自動でメモ化される
const filteredItems = items.filter(item => item.name.includes(filterText));
const handleClick = (id) => {
console.log('Clicked', id);
};
return (
<ul>
{filteredItems.map(item => (
<ItemKey key={item.id} item={item} onClick={handleClick} />
))}
</ul>
);
}
React公式仕様:React Compiler の自動最適化
React 19 のエコシステムとして提供される React Compiler は、ビルド時(Babel / Vite プラグイン)に抽象構文木(AST)を解析し、コンポーネント内のデータフローと依存関係を追跡して、自動的にメモ化処理を注入するコンパイラです。
この導入により、開発者が手動で useMemo, useCallback, React.memo を記述する作業が原則不要となりました。
実際に起こる事故:Rules of React 違反による「サイレント・スキップ」現象
React Compiler公式ドキュメント(react.dev/learn/react-compiler)で明記されている通り、コンパイラはコードの安全性を最優先するため、「Rules of React(Reactの規約)」に違反しているコンポーネントを見つけると、エラーを出さずにそのコンポーネントの自動メモ化処理のみを静かにスキップ(無効化)します。
メモ化が静かにスキップされるコード例
// ❌ 違反例:描画中に既存オブジェクト/props を直接ミューテーション(変更)している
function IncorrectComponent({ user }) {
// レンダー時に props のオブジェクトを変更(純粋関数違反)
user.lastViewed = Date.now();
// ⭕ コンパイラはこのコンポーネントの自動メモ化を断念してスキップする
return <div>{user.name}</div>;
}
導入と移行手順
- プロジェクトのビルド設定(
vite.config.tsやnext.config.js)に React Compiler プラグインを追加する eslint-plugin-react-compilerを導入し、エディタ上で Rules of React 違反箇所(ミューテーションや副作用の誤用)を可視化・修復する- 既存の
useMemo/useCallbackはそのまま動作するため、段階的にリファクタリングして手動フックを削除していく