Server Component とは何か
Server Component は、サーバー側だけで実行され、その JavaScript がブラウザに送られない React コンポーネントです。
何が違うのか
これまでの React では、書いたコンポーネントは最終的にブラウザで動いていました。サーバーが HTML を先に作る構成(SSR)でも、同じコードがブラウザにも送られて、そこでもう一度動きます。
Server Component は違います。サーバーで一度動いて、結果だけを送ります。そのコンポーネントの JavaScript はブラウザに届きません。
これまでの React では、同じコードがサーバーとブラウザの両方へ届いていました。 Server Component では、サーバーで実行した結果だけが届きます。
App Router ではこれが既定
app/ の下に書いたコンポーネントは、何も書かなければ Server Component です。Client Component にしたいときだけ、明示的に宣言します。
この既定が逆だと思っていると、ほぼすべての判断がずれます。まずここを押さえてください。
できること
DB に直接アクセスできる
API を経由する必要がありません。
// app/products/page.tsx
export default async function Page() {
const items = await db.item.findMany()
return <List items={items} />
}
自分自身の API ルートを fetch で呼ぶ書き方をよく見かけますが、Server Component では遠回りです。サーバーの中にいるので、直接読めます。
秘密を扱える
API キーや DB の接続情報を、そのまま使えます。このコードはブラウザに届かないからです。
ただし渡した props はブラウザに届きます。ここが分かれ目です。
// これは安全(key はサーバーの中だけ)
const data = await fetch(url, { headers: { Authorization: key } })
// これは漏れる(key が props としてブラウザへ届く)
return <Panel apiKey={key} />
async にできる
コンポーネントそのものを async にして await できます。データ取得のために useEffect と状態を組む必要がありません。
できないこと
| Server Component | Client Component | |
|---|---|---|
| DB に直接アクセスする | できる | できない |
| 環境変数の秘密を読む | できる | できない |
| async / await で書く | できる | できるが用途が違う |
| useState / useEffect | できない | できる |
| onClick などのイベント | できない | できる |
| window / localStorage | できない | useEffect の中でのみ |
| できないこと | 理由 |
|---|---|
useState useReducer | 状態はブラウザ側のもの |
useEffect | 描画後の副作用はブラウザ側のもの |
onClick などのイベント | 押すのはブラウザ |
window document | サーバーに存在しない |
localStorage | 同上 |
これらが必要になった時点で、その部分だけを Client Component に切り出します。
何がブラウザに届くのか
Server Component が返した内容は、HTML と RSC ペイロードという形で送られます。コードではなく、描画の結果です。
つまり、
- 表示している値は届く(当然、画面に出るので)
- 表示していない値も、props として渡していれば届く
- コンポーネントの中で使っただけの変数は届かない
「画面に出ていないから安全」ではありません。境界を越えた props はすべて届きます。
使い分けの目安
まず Server Component で書き始めて、ブラウザが必要になったところだけを切り出すのが基本です。
越えられる: 商品名・価格・レビュー本文などの値
越えられない: DB への問い合わせ
越えられない: 秘密の読み出し
逆に「とりあえず全部 Client にして、必要なら Server に戻す」という進め方は、送る JavaScript が増えるうえ、DB へ直接アクセスできる利点も失います。
よくある誤解
SSR と同じもの?
違います。SSR は「同じコードをサーバーでも動かす」仕組みで、コードはブラウザにも送られます。Server Component はそもそもブラウザに送らない仕組みです。両方を同時に使うこともできます。
静的なページ専用?
違います。リクエストごとに実行することもできます。何をいつ実行するかは、Cookie や検索パラメータを読むかどうかなどで決まります。
遅くなる?
送る JavaScript が減るぶん、ブラウザ側の負担は軽くなります。ただしサーバー側の処理が遅ければページ全体が遅くなるので、そこは Suspense で分割します。
出典
- nextjs.org/docs/app/getting-started/server-and-client-components
- react.dev/reference/rsc/server-components
このページの内容は上記の一次情報を基準に書いています。個人ブログや二次情報を根拠にしていません。