Skip to main content

React 18 から 19 へのアップグレードプレイブックを作成

公式の React 19 アップグレードガイドを、コードベースに対応させた段階的なプレイブックに落とし込みます。
AuthorCognition
Category移行
Features高度, プレイブック
1

React 19 アップグレードガイドを Advanced Devin にプロンプトとして与える

React 19 では、ref の扱い、コンテキストの利用方法、TypeScript の型、廃止されたレガシー API などに、後方互換性を破壊する変更が導入されています。公式アップグレードガイドにはすべての変更が記載されていますが、難しいのはそれらを 自分たちの コードに対応付けることです。自分でガイドを読み、すべてのコンポーネントを精査する代わりに、ガイドとコードベースの両方を Advanced Devin に渡して、実際のファイルを対象にしたプレイブックを生成させましょう。Devin のホームページの入力ボックス下にある Advanced ボタンをクリックして Advanced Devin を開き、アップグレードガイドの URL と必要な内容を含むプロンプトを貼り付けてください:
2

コードベース固有のコンテキストを付与する

Advanced Devin は、あなたのリポジトリのアーキテクチャを自動的に理解するために DeepWiki を使用します。また、React 19 に関するオンライン情報源 ― 公式アップグレードガイド、ブログ記事、ライブラリの変更履歴 ― も参照し、そこで得た内容を直接プレイブックに取り込むことができます。プレイブックの精度をさらに高めるために、移行で影響を受けるパターンについて Devin に伝えてください:
  • src/components/ui/ 配下の 23 個のコンポーネントで forwardRef を使っています — これらは私たちのデザインシステムのプリミティブです”
  • src/legacy/ には、まだ文字列 refs と componentWillMount を使っているクラスコンポーネントが 4 つあります”
  • “組織内の他のリポジトリ(例: acme/design-system, acme/admin-dashboard)を確認して、すでに React 19 への移行を始めているかどうかを確認し、そこで確立されたパターンがあれば再利用してください”
依存ライブラリごとに React 19 互換性ガイド(例: React Router、React Hook Form、あるいは使用している UI ライブラリ)が用意されている場合は、それらの URL もプロンプトに貼り付けてください — Devin がすべて読み込み、破壊的変更を照らし合わせて確認します。
3

コードベースごとのプレイブックを確認する

Devin は React 19 のアップグレードガイドを最初から最後まで読み込み、すべての後方互換性のない変更を、DeepWiki を通じてあなたのコードベースと照合し、対象ファイル、複雑さの見積もり、検証ステップを含むフェーズごとのプレイブックを作成します。
# React 18 → 19 移行プレイブック

## フェーズ1: React 18.3へのアップグレードと非推奨警告の修正 (S)
- npm install react@18.3 react-dom@18.3
- アプリを実行し、コンソールの非推奨警告をすべて修正する:
  - src/legacy/OldModal.tsx、src/legacy/OldTooltip.tsx の文字列 ref を削除する
  - src/legacy/DropdownMenu.tsx の ReactDOM.findDOMNode を置き換える
- テストスイートを実行してリグレッションがないことを確認する
- 検証: 開発コンソールに非推奨警告がゼロ、すべてのテストが通過

## フェーズ2: forwardRef から ref-as-prop への移行 (M)
- src/components/ui/ 内の23コンポーネントから forwardRef ラッパーを削除する:
  - Button.tsx、Input.tsx、Select.tsx、TextArea.tsx(使用頻度高)
  - Modal.tsx、Popover.tsx、Tooltip.tsx(使用頻度中)
  - +16コンポーネント(全リストは下記)
- forwardRef でラップする代わりに ref を通常の prop として渡す
- TypeScript 型を更新: RefObject<T> を RefObject<T> | null に変更する
- 新しい React 19 の ref セマンティクスに合わせて src/types/refs.d.ts を更新する
- 検証: すべての ref フォワーディングコンポーネントがレンダリングされ、フォーカス管理が機能する

## フェーズ3: 非推奨 API の削除 (M)
- レガシー Context(contextTypes/getChildContext)を以下で置き換える:
  - src/legacy/ThemeProvider.tsx → すでに createContext を使用(変更不要)
  - src/legacy/LocaleContext.tsx → createContext パターンに変換する
- 12ファイルから propTypes を削除する(TypeScript がバリデーションを担当)
- 関数コンポーネントから defaultProps を削除する(JS のデフォルト値を使用)
- 検証: Context の値が正しく伝播し、実行時警告がない

## フェーズ4: データフェッチと Suspense パターンの更新 (L)
- src/components/layouts/ の Suspense 境界を確認する
- フォールバック動作の変更に依存するコンポーネントを更新する
- 新しい Suspense セマンティクスで src/routes/ の遅延ロードルートをテストする
- 検証: すべての遅延ルートが読み込まれ、ローディング状態が正しくレンダリングされる

## フェーズ5: React 19 のインストールと新機能の採用 (M)
- npm install react@19 react-dom@19
- src/hooks/useFormField.ts の useFormState を useActionState に置き換える
- react-dom のインポートを更新: ReactDOM.render → すでに createRoot を使用
- 新しい JSX トランスフォームが未有効の場合は有効化する
- 検証: テストスイート全体が通過し、アプリがエラーなく動作する

## フェーズ6: サードパーティライブラリの更新 (L)
- react-hook-form → v8 にアップグレード(React 19 対応)
- @radix-ui/react-* → 最新版にアップグレード(ref-as-prop サポート)
- react-router-dom → v6.4+ との互換性を確認する
- 検証: フォームが正しく送信され、UI プリミティブがレンダリングされ、ルーティングが機能する

## リスク
- forwardRef の削除は変更量が最も多い — 23コンポーネント、多くが他チームによって使用されている
- TypeScript の ref 型変更により null 安全性の問題が表面化する可能性がある
- react-hook-form v8 には独自の破壊的変更がある — フォームのバリデーションを十分にテストすること
このプレイブックは実際の移行作業そのものではなく、あくまで計画です。チームでレビューし、フェーズやスコープを調整したうえで、どのように実行するかを決定してください。
4

実行とスケール

プレイブックの内容が問題なさそうであれば保存し、セッションに添付してフェーズごとに実行します:リポジトリ横断でスケール — 同じアップグレードが必要な複数の React アプリがある場合は、Advanced Devin の batch sessions を使って、保存したプレイブックをすべてのリポジトリで並列実行できます。