🧹

React 19に備えた1年間の棚卸し:お片付けはこまめに

に公開

本記事はクラスター Advent Calendar 2025の7日目の記事です。

はじめに

2024年12月5日、React 19が正式リリースされました。あれからちょうど1年。つい先日脆弱性が報告され話題にもなっていましたね。

メタバースプラットフォーム「cluster」ではcluster.muというWebページ[1]を持っていますが、このページはReactで構築されています。今回はcluster.muのReact 19マイグレーションの進捗を報告します。1年かけて依存パッケージの棚卸しと対応を進めてきた成果と、残りの課題をまとめます。

https://cluster.mu/

棚卸しで見つかった課題

React 19へのアップデートにあたり、まず依存パッケージの棚卸しを行いました。pnpm why reactでReactに依存しているパッケージを洗い出し、それぞれのReact 19対応状況をGitHub Issuesやリリースノートで確認していきました。

結果、対応が必要なパッケージがいくつか見つかりました。

パッケージ 問題
@testing-library/react-hooks React 18で非推奨、React 19で動作しない
react-test-renderer React 19で非推奨
styled-components アップデートが必要
react-dnd メンテナンス停止、React 19非対応
react-window アップデート推奨
react-helmet React 19非対応
react-color 5年間更新なし
formik 型定義の互換性に問題

対応完了したこと

2025年、以下の対応を完了しました。

時期 パッケージ 対応方法
7月 @testing-library/react-hooks @testing-library/reactのrenderHookに移行
7月 react-test-renderer 削除、テストをwaitForベースに書き換え
7月 styled-components v6.1.19にアップデート
10月 react-dnd @dnd-kit/coreに移行
11月 react-window v2にアップデート

テストライブラリの整理

@testing-library/react-hooksはReact 18で非推奨となり、@testing-library/reactに統合されました。renderHookを使った書き方に移行しています。

// Before
import { renderHook } from '@testing-library/react-hooks';
const { result } = renderHook(() => useMyHook());

// After
import { renderHook } from '@testing-library/react';
const { result } = renderHook(() => useMyHook());

react-test-rendererも削除し、非同期処理のテストはwaitForを使う形に統一しました。

react-dnd → dnd-kit移行

react-dndはメンテナンスが停止しており、React 19への対応も見込めませんでした。

当初は「ドラッグ&ドロップ機能ごと削除する」案もありました。しかし検討の結果、dnd-kitへの移行を選択。判断のポイントは以下の通りです。

  • ユーザー影響: 機能削除がユーザー体験を明確に損なう(代替手段を提供するにも検討コストが高い)
  • 移行コスト: dnd-kitへの移行は許容範囲内
  • 移行先の健全性: dnd-kitはアクティブにメンテされている

「削除」や「移行」で迷ったときは、この3点で評価すると判断しやすいかもしれません。

react-window v2アップデート

react-windowは長らくメンテナンスが滞っていましたが、2025年8月にv2がリリースされました。

インターフェース変更を含むメジャーアップデートだったので、AIと会話しつつ慎重に修正を進めました。

残っている課題と方針

あと少しで、React 19にアップデートできる状態です。

パッケージ 現状 方針
react-helmet React 19非対応 React 19のDocument Metadata機能へ移行
react-color 5年間更新なし react-colorfulへの移行を検討
formik 型定義の互換性問題 skipLibCheckしているので導入はおそらく可能

react-helmet → Document Metadata

React 19ではネイティブのDocument Metadata機能が追加されました。<title><meta>タグをコンポーネント内で直接記述できるようになります。

// React 19
function BlogPost({ post }) {
  return (
    <article>
      <title>{post.title}</title>
      <meta name="description" content={post.excerpt} />
      {/* ... */}
    </article>
  );
}

react-helmetへの依存をなくし、React 19のネイティブ機能に移行する予定です。

うまくいったこと

日頃からのライブラリアップデート

React 19対応がスムーズに進められているのは、日頃からライブラリアップデートを継続していたことも大きいと感じています。これまでrenovateを活用して依存パッケージを定期的に更新し、技術的負債を溜めないようにしてきました。

最近ではアップデート差分のチェックをClaude Codeに任せることが多くなっています。定型的な情報収集をお任せして、自分はその妥当性の判断のみ、という流れです。

storybookのアップデート例


特に、React 19対応とは直接関係ないものの、以下の対応を事前に済ませていたことが大きかったです。

React Router v7移行

React 19リリース直後の2024年12月に、React Router v7への移行を完了しました。

React Router v7はReact 19を強くサポートしており、先に移行しておくメリットがあると判断しました。移行にあたっては、v7で導入されるfuture flagsを事前にopt-inして段階的に対応を進めました。

Redux脱却

2025年3月、長年使用していたReduxを完全に削除しました。

Reduxは機能的には問題なく動作しますが、TanStack QueryやContextの利用により役割が薄れていました。

段階的に移行を進め、以下のように置き換えました。

  • APIレスポンスのキャッシュ → TanStack Query
  • UIのローカルステート → useState/useReducer
  • 複数コンポーネント間で共有するステート → Context + hooks

Reduxを残したままReact 19に移行することも可能でしたが、依存パッケージを減らしておくことで将来のアップデートがさらに楽になります。

早めの棚卸しが大事

React 19リリース直後に依存パッケージの調査を開始したのは正解でした。対応が必要なパッケージを早期に把握できたことで、計画的に作業を進められました。

段階的に進める

一気に全部やろうとせず、パッケージごとに段階的に対応しました。テストライブラリ → react-dnd → react-window と、影響範囲を限定しながら進めることで、問題が起きても切り分けやすくなります。

まとめ

React 19リリースから1年。依存パッケージの棚卸しと対応を地道に進めてきました。

カテゴリ 内容
React 19対応で必要だったパッケージ 5つ対応完了、3つ対応予定
事前に済ませていた対応 React Router v7移行、Redux脱却

パッケージのアップデートはどうしてもメイン業務とはなりにくく、日頃からの依存パッケージの健全性チェックが重要です。renovateによる継続的なアップデートと、大きな依存の事前整理が、React 19対応をスムーズにしてくれました。

来年のアドベントカレンダーでは「React 19移行完了しました」と書けることを願って、あとひと踏ん張り。

参考リンク

脚注
  1. 3D空間を楽しむためのサポートがメインのWebページです。 ↩︎

Discussion