本セッションの登壇者
セッション動画
よろしくお願いします。「Ready for React v.19」というタイトルで発表したいと思います。
最初に簡単に自己紹介です。@koba04というアカウントでXなどをやっています。
今年の1月からメルカリのフロントエンジニアとして働いていて、並行して引き続きSmartHRのフロントエンドの技術顧問をしています。React関連のOSSのコントリビュータやメンテナ、Reactの日本語サイトのメンテナもやっています。
今日は、次のメジャーバージョンに入りそうな機能を大きく3つに分けて簡単に紹介します。React 19に関しては、来月React Confというカンファレンスが開催されるので、そこで発表されるのではと予想しています。リポジトリを見ても開発が活発に行われているようです。
新機能はRSCと「アクション」
Reactの新機能に関して改めて整理すると、Reactは昨年ぐらいからCanaryチャンネルでまだstableではない機能をどんどんリリースしています。
Next.jsでApp Routerを使うと、このCanaryチャンネルを利用するようになっているので、今日紹介するまだstableになっていない機能も使えます。
ただ、このチャンネルには破壊的変更も含まれるので自己責任で使う必要があって、Next.jsの場合はそこをうまくハンドリングしながら、フレームワークでラップしてリリースしている形です。
Reactの新しいプロジェクトを始める時にいくつか選択肢がありますが、公式にはNext.jsやRimixといったフレームワークの利用が推奨されています。今日紹介するような高度な機能をフレームワークに任せることで、より良いユーザー体験を提供するアプリケーションを簡単に作れて、自分たちが作りたいものにフォーカスできるようにしたいのだと思います。
最初にServer Component(RSC)とServer Actionです。
RSCは一言で言うとサーバーでしか実行されないコンポーネントです。
今までもReactはサーバーサイドレンダリングを行っていましたが、その場合はサーバーでコンポーネントを実行してHTMLを生成した後、クライアント側でも同じように実行して同じ結果を生成した上で、イベントをアタッチしてハイドレーションをやるという形でした。
一方RSCでは、コンポーネントのコードがクライアント側には配信されない点が大きく違います。それによって、DBアクセスなどサーバーでしか実行できないコードを安全に書くことができ、生成結果だけがクライアント側に配信されます。
関連して、APIにuseやcacheが入りました。基本的にはRSCと組み合わせた使用が推奨されます。useは、プロミスから値をアンラップできる(取り出せる)APIで、使い方としては、サーバーからプロミスをクライアント側に渡して、クライアント側で結果を読み取れます。cacheは、同じ関数を実行した場合に結果をキャッシュして何回も実行されないようにするもので、たとえばレンダリングで同じフェッチが複数回走らないようにできます。
Server ActionはRSCと逆で、クライアントからサーバーにデータを送信するための仕組みです。これまでデータの更新は別途APIエンドポイントを立ててやっていましたが、サーバーでのみ実行される関数をクライアント側からインポートして実行できます。
裏側では内部的にPOSTリクエストを発行し、渡されたデータを元に、サーバー側でサーバーアクションが実行されるという仕組みです。
新しいAPIとしてはuseActionStateというサーバーアクションの結果を取り出せるAPIや、useOptimisticという楽観的更新ができるAPI、requestFormResetというフォームの値をリセットするAPIが提供されています。基本的にロジックを適切な場所(クライアント/サーバー)で行うための仕組みです。
イメージとしてはReactのツリーがあって、上の方がサーバー、下の方がクライアントで動く形になります。ReactElementとして出力したサーバーコンポーネントの結果を組み合わせて処理します。ツリー的にはクライアントコンポーネントの下にサーバーコンポーネントを置くこともできます。
サーバーアクションの例です。左側がサーバーアクションでuse server
と書くとサーバーで実行される関数になり、その中でクライアントから受け取ったデータを処理します。呼び出し側は普通にこの関数をインポートして呼ぶ他、フォームのアクションに渡してフォームをsubmitした時に自動的に呼ぶこともできます。このアクションという概念は、Astroなどでも検討されていて、これから広まっていくのではないかと思います。
これまでサーバーサイドレンダリングにしても、基本的にはReactはクライアント側でツリーを作って更新していくという流れでした。しかしこれからは、アプリケーションやサーバーも含めて、全体でReactの巨大なツリーを作って、その一部はサーバーで動作して、その一部はクライアント側で動作するようになります。
サーバーとクライアントという不安定で不確実な一番のボトルネックをいかに最適化していくかという課題を、フレームワークやReactでうまくハンドリングしていくことで、より良いユーザー体験を提供していくようになります。詳細については、いろいろな発表があるのでそちらを参照してみてください。
レガシーAPIを廃止、クローニングをやめてパフォーマンス改善、カスタムエレメント対応
ここからは他の細かい更新の紹介です。最初がPass refs as normal propsです。
これまでRefsを受け取る時はforwardRef
でコンポーネントをラップして、別の引数で受け取っていましたが、普通のpropの一部として渡されるようになります。
次がString Refsで、クラスのコンポーネントでRefsに文字列を指定して参照できたのが使えなくなります。v19では、このようにこれまでDeprecatedされていたAPIが結構削除されます。ただ、影響が大きいものはまだ削除対象にはなっていなくて、比較的対応しやすいものが中心だと思います。
defaultProps on Function Componentというのは、ファンクションコンポーネントに対してdefaultProps
というプロパティを設定してオブジェクトを渡すことができなくなるもので、普通にデフォルト引数を使えば良いです。
Legacy Contextは、childContextTypes
をクラスのプロパティで渡せるものですが、たぶん誰も使ってないので大丈夫かなと思います。Spread keysはこの後でまた紹介します。
React.createFactoryというのは、これはもう誰も知らないと思いますが、昔は結構JSXを書きたくなくてReact.createElementを直接書く人がいて、そのために便利なFactory関数を作るものです。
renderToStaticNodeStreamはレガシーなサーバーサイドレンダリングAPIになります。
Intermediate Componentも、クラスが導入される前のJavaScriptでクラスっぽいことをしようとした時のパターンをサポートしていたのを止めますということです。最後に、act
というテストで使う関数をimportする場所が変わります。
これまで紹介したいくつかのAPIの削除に関わっているのがDon’t clone props objectです。ReactElementに対して渡されたPropsが全部一度クローンされていたのをしなくなります。
React.createElement
の呼び出しはかなりホットパスな部分なので、オブジェクトを無駄に作らないのはパフォーマンス改善の効果があると考えられます。
先ほどrefが直接Propsの中に入ってくるというのはまさにこのためで、今までは入らないように一度クローンして取り出していたのですが、そのまま渡す形になっています。そもそもクローンしていたのは、昔はReact.createElementを直接呼ぶケースがあって、その後にPropsが変更される可能性があったからですが、今はもうほとんど直接呼ぶことはなく安全にできるようになりました。
keyに関しては、コンパイル時にPropsではない別の引数として渡されるように変更されたので特に問題ないのですが、スプレッドの中に埋め込まれるとそれができないので、警告が出るようになります。これでどの程度パフォーマンスが最適化されるかはまだ分かりませんが、こういった変更が入っています。
あとはWeb Components Support。Web Componentsと言うと主語が大きいですが、内容はカスタムエレメントに対するプロパティサポートやカスタムイベント対応になります。
長引いていたのは、具体的な実装のほか、破壊的変更になるので次のメジャーバージョンアップを待っていたためと思われます。アプローチとしてはPreactと似ていて、カスタムエレメントに対してプロパティがセットされたらプロパティとして、そうでなければ属性としてセットして、on***
ならば関数として扱うといった実装になっています。
その他細かいものとしては、最初のAdd Diffs to Hydration Warningsは、ハイドレーションが起きた時にdiff形式で出るようになるので、わかりやすくなります。これはすでにCanaryチャンネルでも使えるようになっています。
BigInt supportは、BigIntがレンダリングできるようになります。
Document MetadataとAsset Loadingはタイトル、スタイル、リンクなどのメタ属性に対応するものです。コンポーネントの中にタイトルを書いたらヘッダーの中に埋め込むといった、React Helmetのような外部ライブラリでやっていたことが本体でできるようになります。
ドキュメントが翻訳されているので、興味があれば読んでみてください。preconnect
など、関数もいろいろ入っています。
コンパイラはまだ不明
最後ですが、Reactコンパイラについて紹介したいと思います。
v19に入るかどうかは分かりませんが[後の発表でv19リリース時点では入らないことが判明]これまでuseMemo
やuseCallback
、memo
を使って行っていた最適化をコンパイラが自動でやってくれるという結構野心的なプロジェクトです。
現状としてはMetaですでにInstagramやQuest Storeでプロダクションでの検証をしている段階で、うまくいけば、最適化を手動で行う必要性が減るかもしれません。
近々リリースされるReact 19に入りそうな機能を紹介しました。興味のある人はぜひ来月のReact Confを見てください。ありがとうございました。
sfjjqs