React17 + MUI DateTimePicker + React Hook Form なアプリを yarn upgrade --latest したら破壊的変更が入っていたので修正した

以前、 React17 + MUI + React Hook Form なアプリを作り、以下のリポジトリとして保存していました。
https://github.com/thinkAmi-sandbox/react_mui_with_vite-sample

 
公開から時間が経過していたこともあり、せっかくなので最新のReactなどに追随するべくアップグレードを考えました。

個人のリポジトリだし多少壊れてもいいだろうと考え yarn upgrade --latest したところ、いくつかの機能が動かなくなっていました。

そこで、動くように対応した時のメモを残します。

 
目次

 

環境

アップグレード前

GithubのREADMEのものを転載します。

  • React.js 17.0.2
  • React Router 6.2.1
  • @mui/material 5.2.4
  • @mui/lab 5.0.0-alpha.60
  • @mui/x-data-grid 5.0.1
  • date-fns 2.27.0
  • TypeScript 4.5.2
  • Vite.js 2.6.14
  • Jest 27.3.1
  • use-react-router-breadcrumbs 3.0.1
  • react-hook-form 7.22.2

 

アップグレード後

  • React.js 18.2.0
  • React Router 6.3.0
  • @mui/material 5.9.0
  • @mui/x-data-grid 5.13.1
  • @mui/x-date-pickers 5.0.0-beta.1
  • date-fns 2.28.0
  • @date-io/date-fns 2.14.0
  • TypeScript 4.7.4
  • Vite.js 3.0.0
  • Jest 28.1.3
  • use-react-router-breadcrumbs 3.2.1
  • react-hook-form 7.33.1

 

yarn upgrade --latest ですべて最新化

yarn upgrade --latest を実行して、各パッケージを最新化します。

 

破壊的変更への対応

アップグレード後、動作しなくなったり、エラー・ワーニングが出ていたりしたので、それらに対応していきます。

 

React 18 まわり

Client Rendering APIs の変更に対応

React 18から Client Rendering API に変更が入ったため、対応します。
https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#updates-to-client-rendering-apis

今回はドキュメント通りに修正すれば問題ありませんでした。

差分はこんな感じです。
https://github.com/thinkAmi-sandbox/react_mui_with_vite-sample/commit/6e51aa84c1a7ed8faeb1fa6a060a10bb9f12310c

 

MUI まわり 

DateTimePicker まわりの破壊的変更に対応

今回のアプリでは MUI の DateTimePicker を使っています。

MUIのドキュメントによると、 DateTimePicker 系のコンポーネントが書き直されたようです。

⚠️ The date picker components were rewritten. In most places, the logic was rewritten from scratch, so it isn't possible to maintain the whole list of changes. Here's an overview of the most important concepts that were changed. If you are going to upgrade, the easiest way might be to go through each picker usage in your codebase, and rewrite them one at a time. Don't forget to run your tests after each!

Migration from @material-ui-pickers - Material UI

 
以下で修正点をあげていきます。

 

importするパッケージ変更に対応

今までの @mui/lab パッケージではなく、固有のパッケージを import するようになりました。

  • DateTimePickerLocalizationProvider
    • 変更前
      • mui/lab
    • 変更後
      • @mui/x-date-pickers 関係
  • AdapterDateFns
    • 変更前
      • @mui/lab/AdapterDateFns
    • 変更後
      • @mui/x-date-pickers/AdapterDateFns
  • date-fns のアダプター
    • 追加
      • @date-io/date-fns

 
今までの package.json には記載されていないパッケージもあったため、以下のように追加でインストールします。

yarn add @mui/x-date-pickers

yarn add @date-io/date-fns

 
次に import を変更します。

- import {DateTimePicker, LocalizationProvider} from '@mui/lab'
- import AdapterDateFns from '@mui/lab/AdapterDateFns'

+ import {DateTimePicker} from '@mui/x-date-pickers/DateTimePicker'
+ import {LocalizationProvider} from '@mui/x-date-pickers'
+ import {AdapterDateFns} from '@mui/x-date-pickers/AdapterDateFns'

 
コミットだとこのあたりです。
https://github.com/thinkAmi-sandbox/react_mui_with_vite-sample/commit/166a8fa5bf76ee69cf200ffa4df7bd1e588f77f9#diff-230f0842f24ca99f8edf5e719bf17de385c572e313039903e9e396c644156191L3-R5

 

LocalizationProvider の locale を adapterLocale へ変更

import の変更だけを行った場合、 LocalizationProvider を使っているコンポーネントで以下のエラーが出ます。

LocalizationProvider's prop `locale` is deprecated and replaced by `adapterLocale`

 
MUIのドキュメントを見ると、現在の実装では locale ではなく adapterLocale になっていました。
https://mui.com/x/react-date-pickers/localization/#translation-keys

 
そこで手元の実装も、 adapterLocale を使うように修正します。
https://github.com/thinkAmi-sandbox/react_mui_with_vite-sample/commit/27889dd5b0fbdba69a3f5af162fbbcb56ebf2443

- <LocalizationProvider dateAdapter={AdapterDateFns} locale={ja}>

+ <LocalizationProvider dateAdapter={AdapterDateFns} adapterLocale={ja}>

 

React Hook Form まわり

React Hook Formではそこまで大きな変更がなく、型の追加となりました。

 

useForm に型を追加

React Hook Form をアップグレードしたところ、 useFrom のところでコンパイルエラーが出ていました。

React Hook Form の公式ドキュメント(TypeScript版)を見たところ、 useForm で型を指定していました。
https://react-hook-form.com/get-started/

そこで、今まで型がなかったuseForm に対し、型を追加しました。
https://github.com/thinkAmi-sandbox/react_mui_with_vite-sample/commit/71ea8381c1abadf5943da9f7cd038763d483ab55

- const {control, handleSubmit, setValue} = useForm()

+ const {control, handleSubmit, setValue} = useForm<FormInput>()

 

setValueの引数の型を修正

useForm に型を与えたことにより、 setValue の引数の型も明確になりました。

そこで、既存の型を修正し、 null 許可にしました。

type FormInput = {

- inputValue: Date

+ inputValue: Date | null

}

 

ソースコード

Githubに上げました。
https://github.com/thinkAmi-sandbox/react_mui_with_vite-sample

今回のプルリクはこちらです。
https://github.com/thinkAmi-sandbox/react_mui_with_vite-sample/pull/8