React Labs: 最近の取り組み – 2024年2月

2024年2月15日 Joseph Savona, Ricky Hanlon, Andrew Clark, Matt Carroll、そしてDan Abramov執筆


React Labs の記事では、活発に研究開発中のプロジェクトについて執筆しています。前回の前回のアップデートから大きな進展がありましたので、その進捗状況を共有したいと思います。

補足

React Conf 2024 は、ネバダ州ヘンダーソンで 5 月 15 日から 16 日に開催されます!React Conf に直接参加することにご興味がある方は、2月28日までチケット抽選にご応募いただけます。

チケット、無料ストリーミング、スポンサーシップなどについての詳細は、React Conf のウェブサイトをご覧ください。


React Compiler

React Compiler は研究プロジェクトではなくなりました。このコンパイラは現在 instagram.com の本番環境で稼働しており、Meta の他の場所でもコンパイラを展開し、最初のオープンソースリリースに向けて準備を進めています。

以前の投稿で説明したように、React は状態が変化したときに、時々レンダリングしすぎてしまうことがあります。React の初期の頃から、このようなケースへの対策は手動でのメモ化でした。現在の API では、これは useMemouseCallback、および memo API を適用して、状態が変化したときに React がどの程度レンダリングするかを手動で調整することを意味します。しかし、手動でのメモ化は妥協です。コードが煩雑になり、間違えやすく、最新の状態に保つための余分な作業が必要になります。

手動でのメモ化は妥当な妥協策でしたが、私たちは満足していませんでした。私たちのビジョンは、状態が変化したときに、React の基本的なメンタルモデルを損なうことなく、UI の適切な部分のみを React が自動的に再レンダリングすることです。React のアプローチ(標準の JavaScript 値とイディオムを使用した、状態の単純な関数としての UI)は、React が多くの開発者にとって親しみやすいものである理由の重要な一部であると私たちは考えています。そのため、私たちは React の最適化コンパイラの構築に投資してきました。

JavaScript は、その緩いルールと動的な性質のために、最適化が難しい言語として悪名高いです。React Compiler は、JavaScript のルールと「React のルール」の両方をモデル化することで、コードを安全にコンパイルすることができます。たとえば、React コンポーネントはべき等でなければなりません (同じ入力に対して同じ値を返す) し、props または状態値を変更することはできません。これらのルールは、開発者ができることを制限し、コンパイラが最適化するための安全なスペースを切り開くのに役立ちます。

もちろん、開発者が時々ルールを少し曲げることを理解しており、私たちの目標は、React Compiler ができるだけ多くのコードですぐに動作するようにすることです。コンパイラは、コードが React のルールに厳密に従っていない場合を検出しようとし、安全な場合はコードをコンパイルし、安全でない場合はコンパイルをスキップします。このアプローチを検証するために、Meta の大規模で多様なコードベースに対してテストを行っています。

自分のコードが React のルールに従っているかを確認することに関心のある開発者には、StrictMode を有効にし、React の ESLint プラグインを構成することをお勧めします。これらのツールは、React コード内の微妙なバグを検出するのに役立ち、今日のアプリケーションの品質を向上させ、React Compiler などの今後の機能に対してアプリケーションを将来にわたって使用できるようにします。また、React のルールの統合ドキュメントと、チームがこれらのルールを理解して適用し、より堅牢なアプリを作成するのに役立つ ESLint プラグインの更新にも取り組んでいます。

コンパイラの動作を確認するには、昨秋の講演をご覧ください。講演の時点では、instagram.com の 1 ページで React Compiler を試した初期の実験データがありました。それ以来、私たちは instagram.com 全体でコンパイラを本番環境に展開しました。また、Meta での他の場所への展開とオープンソース化を加速するために、チームを拡大しました。私たちは今後の道のりに興奮しており、今後数か月でさらに多くの情報を共有する予定です。

アクション

以前、データベースの変更を実行し、フォームを実装できるように、サーバーアクションを使用してクライアントからサーバーにデータを送信するためのソリューションを検討していたことを共有しました。サーバーアクションの開発中に、これらの API を拡張してクライアントのみのアプリケーションでのデータ処理もサポートしました。

この機能のより広範なコレクションを、単に「アクション」と呼んでいます。アクションを使用すると、<form/>などの DOM 要素に関数を渡すことができます。

<form action={search}>
<input name="query" />
<button type="submit">Search</button>
</form>

action関数は、同期または非同期で動作できます。標準のJavaScriptを使用してクライアント側で定義することも、'use server'ディレクティブを使用してサーバー側で定義することもできます。アクションを使用すると、Reactがデータ送信のライフサイクルを管理し、フォームアクションの現在の状態とレスポンスにアクセスするためのuseFormStatususeActionStateのようなフックを提供します。

デフォルトでは、アクションはトランジション内で送信されるため、アクションの処理中も現在のページはインタラクティブな状態を保ちます。アクションはasync関数をサポートしているため、トランジションでasync/awaitを使用する機能も追加しました。これにより、fetchのような非同期リクエストが開始されたときに、トランジションのisPending状態を使用して保留中のUIを表示し、更新が適用されるまで保留中のUIを表示できます。

アクションと並行して、オプティミスティックな状態更新を管理するためのuseOptimisticという機能も導入しています。このフックを使用すると、最終的な状態がコミットされると自動的に元に戻る一時的な更新を適用できます。アクションの場合、これにより、送信が成功すると仮定して、クライアント側でデータの最終状態を楽観的に設定し、サーバーから受信したデータの値に戻すことができます。通常のasync/awaitを使用するため、クライアントでfetchを使用している場合でも、サーバーからのサーバーアクションを使用している場合でも、同じように機能します。

ライブラリの作成者は、useTransitionを使用して、独自のコンポーネントにカスタムのaction={fn}プロパティを実装できます。私たちの意図は、React開発者に対して一貫したエクスペリエンスを提供するために、ライブラリがコンポーネントAPIを設計する際にアクションパターンを採用することです。たとえば、ライブラリが<Calendar onSelect={eventHandler}>コンポーネントを提供する場合、<Calendar selectAction={action}>APIも公開することを検討してください。

最初はクライアント-サーバー間のデータ転送のためにサーバーアクションに焦点を当てていましたが、Reactの哲学は、すべてのプラットフォームと環境で同じプログラミングモデルを提供することです。可能であれば、クライアントに機能を導入した場合、それをサーバーでも動作させることを目指し、その逆も同様です。この哲学により、アプリがどこで実行されるかにかかわらず動作する単一のAPIセットを作成でき、後で異なる環境にアップグレードするのが容易になります。

アクションは現在、Canaryチャネルで利用可能であり、次のReactリリースで出荷されます。

React Canaryの新機能

React Canariesを、安定したセムバーバージョンでリリースされる前に、設計がほぼ完了した個々の新しい安定機能をすぐに採用するためのオプションとして導入しました。

Canariesは、Reactの開発方法の変更です。以前は、機能はMeta内部で非公開で調査および構築されていたため、ユーザーが目にするのは安定版でリリースされた最終的な洗練された製品だけでした。Canariesを使用すると、React Labsブログシリーズで共有する機能を完成させるために、コミュニティの助けを借りて公開で構築しています。つまり、新機能が完成した後ではなく、完成するにつれて、より早く新機能について知ることができます。

React Server Components、アセットローディング、ドキュメントメタデータ、およびアクションはすべてReact Canaryに搭載されており、これらの機能に関するドキュメントをreact.devに追加しました。

  • ディレクティブ"use client""use server"は、フルスタックReactフレームワーク用に設計されたバンドラー機能です。これらは、2つの環境間の「分割点」をマークします。"use client"は、バンドラーに<script>タグ(Astro Islandsのような)を生成するように指示し、"use server"は、バンドラーにPOSTエンドポイント(tRPC Mutationsのような)を生成するように指示します。これらを組み合わせることで、クライアント側のインタラクティビティと関連するサーバー側のロジックを構成する再利用可能なコンポーネントを作成できます。

  • ドキュメントメタデータ:コンポーネントツリーのどこにでも<title><meta>、およびメタデータ<link>タグをレンダリングするための組み込みサポートを追加しました。これらは、完全にクライアント側のコード、SSR、RSCなど、すべての環境で同じように機能します。これにより、React Helmetのようなライブラリによって開拓された機能の組み込みサポートが提供されます。

  • アセットの読み込み: スタイルシート、フォント、スクリプトなどのリソースの読み込みライフサイクルにSuspenseを統合し、Reactが<style><link><script>のような要素内のコンテンツを表示する準備が整っているかどうかを判断する際に考慮するようにしました。また、リソースの読み込みと初期化のタイミングをより細かく制御できるように、preloadpreinit のような新しいリソース読み込みAPIも追加しました。

  • アクション: 前述の通り、クライアントからサーバーへデータを送信するためのActionを追加しました。<form/>のような要素に action を追加したり、useFormStatus でステータスにアクセスしたり、useActionState で結果を処理したり、useOptimistic でUIを楽観的に更新できます。

これらの機能はすべて連携して動作するため、安定版チャネルで個別にリリースすることは困難です。フォームの状態にアクセスするための補完的なフックなしにアクションをリリースすると、アクションの実用性が制限されます。サーバーアクションを統合せずにReactサーバーコンポーネントを導入すると、サーバー上のデータの変更が複雑になります。

一連の機能を安定版チャネルにリリースする前に、それらが連携して動作し、開発者が本番環境で使用するために必要なものがすべて揃っていることを確認する必要があります。React Canaryを使用すると、これらの機能を個別に開発し、機能セット全体が完了するまで安定したAPIを段階的にリリースできます。

現在React Canaryにある機能セットは完成しており、リリースする準備ができています。

Reactの次のメジャーバージョン

数年間のイテレーションを経て、react@canaryreact@latest へのリリース準備が整いました。上記で述べた新機能は、アプリが動作するあらゆる環境と互換性があり、本番利用に必要なものがすべて揃っています。アセットの読み込みとドキュメントメタデータは、一部のアプリでは破壊的な変更となる可能性があるため、Reactの次のバージョンはメジャーバージョンとなります。React 19 です。

リリースに向けて、まだやるべきことがたくさんあります。React 19では、Web Componentsのサポートなど、長らく要望されていた改善点も追加しますが、これには破壊的な変更が必要です。現在の私たちの焦点は、これらの変更を反映し、リリース準備を整え、新機能に関するドキュメントを完成させ、何が含まれるかを発表することです。

今後数か月で、React 19に含まれるすべての情報、新しいクライアント機能の採用方法、Reactサーバーコンポーネントのサポートを構築する方法について、さらに情報を提供します。

オフスクリーン(アクティビティに改名)。

前回のアップデート以降、調査中の機能を「オフスクリーン」から「アクティビティ」に改名しました。「オフスクリーン」という名前は、アプリの表示されていない部分にのみ適用されることを意味していましたが、この機能を調査する中で、モーダルの背後にあるコンテンツなど、アプリの一部が表示されていても非アクティブになる可能性があることに気づきました。新しい名前は、アプリの特定のパーツを「アクティブ」または「非アクティブ」とマークするという動作をより正確に反映しています。

アクティビティはまだ調査段階であり、残りの作業はライブラリ開発者に公開されるプリミティブを最終決定することです。より完成度の高い機能の出荷に注力するため、この領域の優先度を下げています。


このアップデートに加えて、私たちのチームはカンファレンスで発表を行い、ポッドキャストに出演して、私たちの仕事についてさらに詳しく話し、質問に答えました。

この投稿をレビューしてくれたLauren TanSophie AlpertJason BontaEli WhiteSathya Gunasekaranに感謝します。

読んでいただきありがとうございます。そして、React Confでお会いしましょう