React 19で使えるメモ化を自動化するReact Compilerの使い方

React Compilerとは

React CompilerはReactのコードを自動でメモ化(最適化)してくれる新機能です。

Reactでメモ化が必要なコンポーネントに対して

  • memo
  • useMemo
  • useCallback

みたいな「手動の最適化」をやらないと、パフォーマンスが落ちます。

React Compilerは、これらの最適化を自動でやってくれます。

React Compiler

React Compilerはバージョン17および18でも動作しますが、17と18は正常に動作しないことがあり、最も良く動作するのはReact 19からとなっているので、特に理由がなければReact 19で使用してください。

React 19でReact Compilerを使う方法

まず、React Compilerを試すために以下のコマンドでReact 19の環境をインストールしてみてください。

npm create vite@latest my-react-compiler -- --template react-ts

このコマンドの実行後に以下のコマンドを実行すれば、ViteでReact 19を起動できます。

cd my-react-compiler
npm install
npm run dev

以前はReact 19にするためには「react@beta react-dom@beta」のインストールも必要だったのですが、現在では不要になっています。

「npm list react」を実行すると、現在のReactのバージョンを確認できます。

$ npm list react
my-react-compiler@0.0.0
├─┬ react-dom@19.1.0
 └── react@19.1.0 deduped
└── react@19.1.0

React Compilerを使用するにはbabel-plugin-react-compilerが必要なので、こちらも以下のコマンドでインストールしてください。

npm i -D babel-plugin-react-compiler

React CompilerはSWCは使用不可

React Compilerを使用するにはbabel-plugin-react-compilerが必要なのですが、SWCだとBabelをインストールできないのでReact Compilerは使用不可です。

# ❌ react-swc-tsだとBabelがインストールできないのでReact Compilerは使用不可
npm create vite@latest my-react-compiler -- --template react-swc-ts

メモ化確認のための環境を作成する

メモ化の確認のためにApp.tsxを以下のコードに変更して、CurrentDate.tsxを追加して読み込んでください。

App.tsx
import { useState } from 'react'
import './App.css'
import CurrentDate from './CurrentDate'

function App() {
  console.log('💻 App render')
  const [count, setCount] = useState(0)
  const [date, setDate] = useState<string>('')

  return (
    <>
      <h1>Vite + React</h1>
      <div className="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
        <button onClick={() => setDate(new Date().toLocaleString())}>
          現在の日時を表示
        </button>
      </div>
      <CurrentDate date={date} />
    </>
  )
}

export default App
CurrentDate.tsx
type Props = {
  date: string
}

function CurrentDate({ date }: Props) {
  console.log('🕔 CurrentDate render')

  return (
    <div>
      <h2>現在の日時: {date}</h2>
    </div>
  )
}

export default CurrentDate

修正後に起動して確認をすると、countのボタンをクリックした際に<CurrentDate>コンポーネントもレンダリングされてしまっていることが、console.logの結果から確認できます。

Reactメモ化前のconsole.log結果

React Compilerを有効にしてメモ化を自動化するにはbabel-plugin-react-compilerを読み込む必要があるので、vite.config.tsを以下のように変更して、babel-plugin-react-compilerを読み込んでください。

vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [
    react({
      babel: {
        plugins: [
          ['babel-plugin-react-compiler']
        ],
      },
    }),
  ],
});

babel-plugin-react-compilerを読み込んだあとにcountボタンを押すと、何度押してもConsoleにCurrentDate.tsxの結果が表示されておらず、レンダリングされていないことが確認できます。

Reactメモ化後のconsole.log結果

React Compilerのサンプル