はじめに
「React 18 へのバージョンアップ、やらなきゃいけないけど画面が壊れそうで怖い…」
「とりあえずパッケージを 18 に上げたら何が変わるの?」
そんな疑問を持つ方に向けて、本記事では React 17 から 18 への移行手順 と、最重要ポイントである createRoot の仕組み を初心者にもわかりやすく図解で解説します!
1. React 18 に上げると何が嬉しいの?
React 18 の最大の目玉は 「並行処理(Concurrent Features)」 と 「自動バッチ処理(Automatic Batching)」 です。
難しい言葉に聞こえますが、一言で言うと 「画面の描画パフォーマンスが勝手に上がってサクサク動くようになる」 ということです。
① 自動バッチ処理(Automatic Batching)で無駄な描画が激減!
-
React 17 まで:
// 1回のイベントで複数の状態を更新すると… setCount(c => c + 1); setFlag(f => !f); // → 2回画面が再描画(レンダリング)されていた! -
React 18:
Promise や setTimeout の中も含め、「あ、更新が2つあるね。じゃあ最後に1回だけまとめて描画するね!」 と自動でまとめてくれるようになり、画面のカクつきが劇的に減ります。
2. 最重要ポイント:createRoot への書き換え
React 18 の新機能(自動バッチ処理など)の恩恵を受けるためには、アプリの「起動スイッチ」を新しい書き方に切り替える 必要があります。
ビフォー・アフター(index.tsx)
🔴 React 17 の起動コード(旧式)
import ReactDOM from "react-dom";
import App from "./App";
const container = document.getElementById("root");
// HTMLの箱に直接アプリを流し込んでいた
ReactDOM.render(<App />, container);
🟢 React 18 の起動コード(最新)
import { createRoot } from "react-dom/client"; // ← 'react-dom/client' から呼ぶ!
import App from "./App";
const container = document.getElementById("root");
if (!container) throw new Error("root要素が見つかりません");
// 1. 最新エンジンを搭載した「root」を作成する
const root = createRoot(container);
// 2. そのrootを使ってアプリを描画する
root.render(<App />);
⚠️ 注意:書き換えないとどうなる?
ReactDOM.renderのままでも一応動きますが、コンソールに警告が出て 「React 18 の新機能がすべてOFFになり、昔の React 17 のフリをして動く(互換モード)」 状態になってしまいます。必ずcreateRootに切り替えましょう!
3. 実践!移行の4ステップ
実務では、以下の手順で進めると安全です。
STEP 1: パッケージの更新
まずは react と react-dom、そして TypeScript の型定義を 18 にアップデートします。
# npm の場合
npm install react@^18 react-dom@^18
npm install -D @types/react@^18 @types/react-dom@^18
# pnpm の場合
pnpm add react@^18 react-dom@^18
pnpm add -D @types/react@^18 @types/react-dom@^18
STEP 2: エントリーポイントの書き換え
前述の通り、index.tsx(または index.js / main.tsx)を createRoot に書き換えます。
STEP 3: 型チェックとビルドの確認
# TypeScript の型チェック
npx tsc --noEmit
# ビルド確認
npm run build (または pnpm build)
STEP 4: 画面の動作確認
開発サーバーを起動し、主要な画面が真っ白にならずに正常に動作するか確認します。
4. 現場で学んだ「ハマりどころ」と対策 💡
実際の現場で React 18 移行を行う際、特に気をつけるべきポイントをまとめました。
① 一気に全部やらない(PRを分割する)
大規模なアプリの場合、「React 18 への更新」と「UIライブラリ(Material-UI, Ant Design, Shopify Polaris など)の更新」を同時にやると、不具合が出た時に原因の特定が地獄になります。
- PR 1:データ通信層(Apollo Client / React Query など)の事前更新
-
PR 2:React 18 +
createRootへの切り替え -
PR 3:UIライブラリの追従
と分割して進めるのが安全な王道パターンです。
② 型が any に落ちていないか注意する!
GraphQL Code Generator や外部ライブラリを併用している場合、ライブラリ同士のバージョン不一致で 「型チェックがエラーを出さず、サイレントに any に化けてしまう」 罠があります。
更新後は、主要なフック(useQuery や useState 等)にマウスをホバーし、ちゃんと本来の型が推論されているか確認します。
おわりに
React 17 から 18 へのアップデートは、createRoot の基本さえ押さえれば、破壊的変更も少なく比較的安全に進められる親切なバージョンアップです。
パフォーマンス向上や最新ライブラリの恩恵を受けるためにも、ぜひサクッとアップデートに挑戦してみてください!