フロントエンドの定番ライブラリ「React 19」の新機能を紹介──React Server Componentsとその他の改善点
フロントエンド開発における定番ライブラリ「React」の最新バージョン解説 第5回
ダウンロード サンプルファイル (150.6 KB)
React Server Componentsの正式サポート(2)
事前に描画されるサーバコンポーネント
サーバコンポーネントは、事前に「どこか」でレンダリングされるコンポーネントです。
「どこか」というのは漠然とした表現ですが、Reactでは決まっておらず、クライアントやSSR(Server Side Rendering)サーバーとも限りません。実際にはNext.jsなどのフレームワークや開発者自身が決定することになります。基本的にはビルド時にレンダリングされ、静的なHTMLページとしてクライアントに配信されます。動的なデータ読み込みが必要な場合はSSRサーバーでレンダリングすることもできます。
ブログ記事のように動的な読み込みが不要な場合は前者を、ユーザーのログイン状態などによって動的なデータ読み込みが必要な場合は後者を選択することになります。
サーバコンポーネントの例を見てみましょう。
export default async function Page() {
const fruits = await loadFruitsFromCsv("./fruits.csv");
return (
<ul>
{fruits.map((fruit) => (
<li key={fruit.id}>{fruit.name}</li>
))}
</ul>
);
}
この例では、loadFruitsFromCsv関数でCSVファイルからフルーツのデータを読み込み、リスト表示しています。このコンポーネントが非同期関数になっていることに注目してください。これにより内部で直接awaitが使え、直感的な記述で非同期的なデータ取得ができます。従来のNext.jsにおけるgetServerSidePropsを使った記述と比べると格段にシンプルになっています。
このサンプルでは、Next.jsを静的エクスポートモードにしていますので、ビルド時にデータが読み込まれてコンポーネントがレンダリングされ、静的なHTMLページとして出力されます。従って、Node.jsサーバーは必要なく、npm startでは単なるWebサーバーを動かしています。
フルーツの一覧が描画されていますが、これはクライアント側で描画されたものではなく、ビルド時にサーバで描画されたものです。ページのソースを表示してみると、フルーツ一覧の<li>タグがHTMLとして出力されていることが確認できます(※)。
サーバコンポーネントの詳細については、先行記事 Next.jsの新常識「App Router」を学ぼう!を参照してください。
※厳密には、RSCはHTMLではなくRSC Payloadと呼ばれるJSON形式のデータを生成し、それをもとにHTMLがレンダリングされます。
サーバ側で実行されるサーバ関数
サーバ関数は、その名の通りサーバ側で実行される関数です。サーバ関数はクライアントコンポーネントからインポートして呼びだすこともできるのが特徴です。サーバ関数は、開発中にサーバアクションと呼ばれていたものと同じですが、リリースに際し、より汎用的な名前に変更されました。
サーバ関数はサーバコンポーネントもしくは専用のファイルで"use server"でマークすることで定義します。リスト2ではサーバ関数をサーバコンポーネント内で定義しています。
import fs from "fs/promises";
export function ServerComponent() { // サーバコンポーネント
async function myFirstServerFunction() {
"use server"; // サーバ関数としてマーク
console.log("myFirstServerFunction called!");
await fs.appendFile("log.txt", `myFirstServerFunction\n`);
}
console.log("Server Component rendered!");
return <button onClick={myFirstServerFunction}>Server Component</button>;
}
関数内に"use server"が記述されていることに注目してください。サーバサイドで動作する関数なので、fs/promisesというサーバ環境下(ここではNode.js)でしか機能しないモジュールを使用できています。
リスト3は、リスト2と同様の処理を別ファイルで定義したものです。
"use server";
import fs from "fs/promises";
export async function mySecondServerFunction() {
// Server Function
console.log("mySecondServerFunction called!");
await fs.appendFile("log.txt", `mySecondServerFunction\n`);
}
ファイル先頭で"use server"を記述すると、そのファイル内のすべての関数がサーバ関数として扱われます。このように別ファイルで定義しておくと、リスト4ようにクライアントコンポーネントからインポートして呼び出せるようになります。
"use client"; // クライアントコンポーネントとしてマーク
import { mySecondServerFunction } from "./server-functions";
export function ClientComponent() {
console.log("Client Component rendered!");
return <button onClick={mySecondServerFunction}>Client Component</button>;
}
このサンプル02_react19-nextjs15-server-functionsを実行すると以下のような動作になります。いずれのボタンも関数自体はサーバ側で実行され、log.txtにログが追記されます。
ClientComponentはクライアント側でも描画されるため、ブラウザのコンソールにClient Component rendered!が表示されています。Server Componentはサーバコンポーネントとしてビルド時にレンダリングされているため、実行時にはサーバ側のコンソールにも表示されません。
サーバ関数は第3回で説明したReact19の「アクション」から呼び出したり、<form>アクションの関数として使用したりすることもできます。本記事では割愛しますが、実例はサンプルの03_react19-nextjs15-server-actionsを参照してください。
この記事は参考になりましたか?
- フロントエンド開発における定番ライブラリ「React」の最新バージョン解説連載記事一覧
-
- React 19.2新機能ガイド──cacheSignalの導入とuseIdの改善点解説
- React 19.2新機能ガイド──Activity/useEffectEventを軸に見...
- フロントエンドの定番ライブラリ「React 19」の新機能を紹介──React Serve...
- この記事の著者
-
WINGSプロジェクト 山田 研二(ヤマダ ケンジ)
株式会社MSEN CTO。高校卒業後、大阪大学の研究所で働きながらプログラミングやWebデザインをはじめ、以後20年以上、Webサイト制作や業務システムの構築を手がけています。フリーソフトもいくつか公開しています。好きな言語はC#とTypeScript、趣味は旅行です。 GitHub アカウント < WINGSプロジェクト について>有限会社 WINGSプロジェクト が運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での 登録メンバ は約50名で、現在も執筆メンバを 募集中 。興味のある方は、どしどし応募頂きたい。 著書 、 記事 多数。 RSS X: @WingsPro_info (公式)、 @WingsPro_info/wings (メンバーリスト) Facebook
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
