サーバーからクライアントへ Promise をそのまま渡せる時代へ!
こんにちは、React の世界は日々進化していますね。最近のアップデートで、Server Component から Client Component へ Promise を返して、さらにデータストリーミングができるようになったんです!
この新機能のおかげで、サーバーで作成した Promise をそのままクライアントに渡し、Suspense と連携させることで、シームレスに非同期データを扱えるようになりました!
どういうこと?
簡単に言うと、サーバー側で Promise を生成し、そのままクライアント側で use
API を使って解決できます。今までなら、サーバーサイドで await してからデータを props として渡す必要がありましたが、これでレンダリングのブロッキングを回避できる可能性が広がります。
こんなコードで実現!
まずはサーバー側で Promise を生成してクライアントコンポーネントへ渡す例です。以下は src/App.js
のコードです。
import { Suspense } from "react";
import { fetchMessage } from "./lib.js";
import { Message } from "./message.js";
export default function App() {
// サーバー側で非同期にデータ(Promise)を取得
const messagePromise = fetchMessage();
return (
<Suspense fallback={<p>⌛メッセージを取得中...</p>}>
{/* Promise を props として渡す */}
<Message messagePromise={messagePromise} />
</Suspense>
);
}
次に、クライアント側で Promise を use
フックで解決する例です。こちらは src/message.js
に記述しています。
"use client";
import { use } from "react";
export function Message({ messagePromise }) {
// Promise の解決を待って値を取得
const messageContent = use(messagePromise);
return <p>メッセージ: {messageContent}</p>;
}
この機能がもたらすメリット
-
ストリーミングでのデータ処理
サーバーで Promise を作成し、その Promise をクライアントで解決するため、サーバーの処理がクライアントのレンダリングをブロックしません。 -
簡潔なコード
従来のデータフェッチパターンに比べ、サーバーコンポーネントとクライアントコンポーネントの連携が非常にスッキリしています。
少しだけ注意点
-
use
は React コンポーネントまたはカスタムフック内でのみ使えます。このため、ループや条件分岐の中でも使える柔軟さはありますが、必ずコンポーネント内で呼び出すようにしましょう。 - Promise の解決値はシリアライズ可能である必要があります。関数などシリアライズできない値は渡せないので注意してください。
まとめ
React 19 で追加された use
API を使えば、サーバーで生成した Promise をクライアントにそのまま渡してデータをストリーミングすることが可能になりました。
これにより、データフェッチのパターンが格段にシンプルに!
アプリケーションのパフォーマンス向上やコードの簡潔さを追求する方には、まさに朗報ですね。
React の最新情報については、公式ドキュメントもチェックしてみてくださいね。
React Docs - Streaming data from the server to the client