ENECHANGEの Yuto Ono です。エンジニアリングマネージャーをしながら、フロントエンドの開発もしています。
2024年4月に、React 19 Beta がリリースされました。2024年9月現在、 React 19 はRC版となっており、正式リリース間近となっております。そこで、早めに React 19 の新機能をキャッチアップし、正式リリース時にスタートダッシュをきれるようにしたいと思いました。
最近、実務でアンケート機能の実装をしていることもあり、このようなアンケートアプリケーションを作ってみました。React 19 の機能をふんだんに使ってみましたので、その解説を書いていこうと思います。
- アクション
- useフック
- <Context.Provider> → <Context>
- メタデータのサポート
- refを propsとして受け取れる(forwardRefが不要に)
- その他の新機能・改善
- まとめ
今回のソースコードはこちらのGitHubリポジトリに公開しています。
また、こちらにデプロイしております。よかったら触ってみてください。
https://yuto-ono-react-19-sample.vercel.app/
また今回 React 19 の学習にあたり、React公式ブログと、uhyoさんのZenn本を参考にさせていただきました。この場をお借りして、お礼申し上げます。
アクション
React 19 を語るうえで欠かせないのが、「アクション」という概念です。これは、非同期処理をスマートに実装できる仕組みのようなものです。詳しい説明は、React公式ブログや、uhyoさんの解説記事をご覧ください。
アクションの最も基本的な実装方法は、 useTransition に非同期関数を渡すことです(React 18 にも useTransition がありますが、非同期関数を処理する機能はないのでご注意ください)。なお、他にもアクションを扱う便利なフックがあり、例えば後述する useActionState などがあります。実際にはそちらを使ってアクションを定義することが多いでしょう。
useActionState
useActionState は、アクションの定義とstateの管理を同時にできるものです。useFormState からリネームされただけあって、公式ドキュメントを見ても、フォームとともに使うことを想定されていそうです(もちろん、フォーム以外でも使うことができます)。
また、それに関連して、 form の action に、非同期アクションを指定することができるようになりました。しかも、アクションの引数に formData が渡されるため、入力された値を取得するのも簡単にできるようになりました(公式ドキュメント)。
今後は、フォームが非制御コンポーネント (uncontrolled component) で良い場合は、追加のライブラリなしでも快適に実装できそうです(制御コンポーネント (controlled component) を使う場合は、今まで通り、 react-hook-form などのライブラリを導入するのが良さそうです)。
実際、今回の試作アプリでも、 useActionState を使って、送信途中や、送信後の挙動などをスマートに実装することができました。
useOptimistic
useOptimistic は楽観的更新を行うためのフックです。これを使うと、非同期アクションの完了を待たずに、UIを更新することができます。いいねボタンを押したときにレスポンスを待たずにいいねのカウントが増えるイメージです。これにより、ユーザーにアプリケーションがサクサク動く印象を与えることができます。
実際、今回、フォーム送信処理のモックにわざと1秒のsleepを入れていますが、送信処理が終わるのを待たずにアンケート結果が描画されていることがわかります。
useフック
use はPromiseやContextなどのリソースから値を読み取るためのフックです(公式ドキュメントでは、フックではなくて React API として紹介されていますが、便宜上フックと呼びます)。ただし、今回は、Promiseを読み取るための useは使いませんでした。なぜなら、公式ブログには
プロミスをキャッシュできるサスペンス対応のライブラリまたはフレームワークで作られたプロミスを渡す必要があります。
とあり、現時点では他のライブラリと組み合わせて使うことが前提となっているからです。結局、データフェッチ系は、実務でも使っている、SWR で実装しました。
将来的には、レンダー中にプロミスをキャッシュしやすくする機能を提供する予定です。
とあるので、近いうちに、 React だけでデータフェッチを良い感じに書けるようになるかもしれません。良い感じのキャッシュ機構が開発されるのを楽しみに待ちましょう。
もう1つの、Contextを読み取るための useは、下と関係するので、そこで一緒に言及します。
<Context.Provider>
→ <Context>
今まで <Context.Provider>
と書いていたものが、 <Context>
と書けるようになります。いずれは <Context.Provider>
が非推奨になります(公式ブログ)。ちょっとした改善ですが、読みやすくなっていいですね。
それに関連して、 useContext(Context)
の代わりに、 use(Context)
と書けるようになりました。読みやすくなっただけでなく、柔軟さも増しているようなので、今後はContextに対しては useを優先的に使うことが推奨されます(公式ドキュメント)。
メタデータのサポート
<title>
、<link>
、<meta>
などのメタデータタグをレンダリングするのに、今までは react-helmet のようなライブラリが必要でしたが、React 19 からはメタデータタグを認識して自動的に <head>
セクションに移動してくれるようになりました(公式ブログ)
refを propsとして受け取れる(forwardRefが不要に)
今まで forwardRefを使って回りくどい方法で refを渡していたのが、シンプルに propsで refを受け取れるようになります(公式ブログ)。
その他の新機能・改善
他にも今回紹介しきれなかった新機能・改善が色々あります。ぜひ公式ブログやuhyoさんの記事を参考にしてみてください。
- サーバコンポーネント・サーバアクション
- ハイドレーションエラー時の差分表示
- ref 用のクリーンアップ関数
- useDeferredValue の初期値
- スタイルシートのサポート
- 非同期スクリプトのサポート
- リソースのプリロード
- サードパーティのスクリプトおよび拡張機能との互換性改善
- カスタム要素のサポート
まとめ
React 19 で登場したアクションという概念と、それを扱うための useActionState 、useOptimistic は、非同期処理を実装するうえで、非常に便利だと感じました。きっと周辺ライブラリもアクションに対応してくると思うので、そのへんもウォッチしていきたいなと思いました。それ以外にも嬉しい新機能や改善が色々とあったので、19の正式リリースが楽しみです。
あと、フロントエンド界隈は常に新しい技術や概念が出続けるので、勉強を続けることが大事だと思いました。ぜひ皆さんも常に新しい情報をキャッチアップし続けていきましょう!