旧ブログ(ISSEN)から移行しました

【React】サーバーコンポーネントとは?クライアントコンポーネントとの違い!【初学者向け】

【React】サーバーコンポーネントとは?クライアントコンポーネントとの違い!【初学者向け】

塩見直樹
塩見直樹6分で読めます

はじめに

こんにちは、株式会社TOKOSのナオキです!
今回は、サーバーコンポーネントとはどういったコンポーネントなのか?クライアントコンポーネントの違いについて簡単に説明します!React初学者の方もいるかと思いますので、ぜひ参考にしてください🙌

対象読者

  • React初学者の方
  • サーバーコンポーネントとクライアントコンポーネントの違いについて理解していない方

サーバーコンポーネントとは

サーバーコンポーネントとは、文字通りサーバーでコンポーネントの生成を行いそのコンポーネントデータをクライアントで取得、レンダリングする為のコンポーネントです。
Next.js 13.4がリリースされてから、AppRouterがstableになりました。
そのAppRouterのコンポーネントは、デフォルトでサーバーコンポーネントになっています。

サーバーコンポーネントは、以下のような特徴があります!

  • ステートを持てないため、useStateやuseReducerは使えない
  • 関数はシリアライズ出来ない為、クライアントコンポーネントに関数を渡すことが出来ない
  • async / awaitを使用することができる
  • サーバーコンポーネントは、クライアントコンポーネントを子コンポーネントに持つことができる
  • JavaScriptバンドルサイズが削減され、パフォーマンスが高くなる

※バンドルとは
複数のJavaScriptファイルや使用しているライブラリや依存関係も含めて1つのJavaScriptファイルにまとめることです。

ナオキナオキ

サーバーコンポーネントを使用するメリットってなんだろう?

サーバーコンポーネントを使用するメリット

レンダリングの高速化: サーバーコンポーネントは、サーバーサイドでコンポーネントをレンダリングするため、クライアントサイドでのJavaScriptの実行やDOM操作が発生しません。そのため、初期表示やパフォーマンスを改善できます!

SEOの向上: サーバーサイドでコンテンツが生成されるため、クローラーがページの内容をより正確に理解し、インデックス化できます。そのため、検索エンジンでのランキング向上などが期待できます!

セキュリティの向上: サーバーコンポーネントでは、環境変数を用いたコードをサーバーコンポーネント側で実行することで、クライアント側にセキュアな環境変数を漏洩させることが無くなります!

サーバーコンポーネントとクライアントコンポーネントの違い

1. レンダリング環境

サーバーコンポーネントは、サーバー上でレンダリングされ、クライアントにはHTMLが送られます!
クライアントコンポーネントは、サーバーでプリレンダリングされた後、クライアントでJavaScriptによってハイドレートされます!
レンダリングについて、詳しく知りたい方は、こちらの公式ドキュメントを参照ください!

2. 使用目的

サーバーコンポーネントは、主にデータフェッチやバックエンドリソースへのアクセス、秘密情報の保持、クライアントへ送信するJavaScriptの量を削減するために使用されます!
クライアントコンポーネントは、インタラクティブな機能やイベントリスナー、状態管理、ブラウザ固有のAPIの使用に適しています!

サーバーコンポーネントとクライアントコンポーネントの使い分け方

行いたい処理サーバーコンポーネントクライアントコンポーネント
データフェッチ
バックエンドリソースへのアクセス
機密情報の保持
インタラクティブな機能やイベントリスナー
ステート、エフェクト、カスタムフックの使用

データフェッチ

クライアントコンポーネントでもデータの取得は出来ますが、特別な理由がない限りサーバーコンポーネントでデータを取得するほうが良いです。サーバーコンポーネントを使用すると、データフェッチをデータソースに近いサーバーに移動できます。そのため、レンダリングに必要なデータのフェッチにかかる時間と、クライアントが行う必要があるリクエストの数が削減され、パフォーマンスが向上します!

バックエンドリソースへのアクセス

サーバーコンポーネントは、バックエンドリソースに直接アクセスできます。そのため、APIキーやデータベースへのアクセスなど、サーバー上で行うべき処理はサーバーコンポーネントで行ったほうが良いです!

機密の保持

サーバーコンポーネントでは、トークンやAPIキーのような機密データやロジックをサーバー上に保持しつつ、クライアントにそれらを公開するリスクを回避することが出来ます!

インタラクティブな機能やイベントリスナー

イベントリスナーが必要なコンポーネントは、クライアントコンポーネントとして実装します。これにより、インタラクティブな機能が正しく動作し、ユーザーエクスペリエンスが向上します!

ステート、エフェクト、カスタムフックの使用

サーバーコンポーネントでは、ステートの保持をすることが出来ないためクライアントコンポーネントで使用することになります!

ナオキナオキ

AppRouterは、デフォルトでサーバーコンポーネントになるって事だけど、どうしたらクライアントコンポーネントに変更できるの?

AppRouterでサーバーコンポーネントをクライアントコンポーネントに変える方法

AppRouterでサーバーコンポーネントからクライアントコンポーネントに変えるには、以下のコードのようにモジュールの先頭に"use client"を記述することで変更できます!

app/components/Example.tsx
"use client"
 
import { FC, ReactNode, memo } from "react"
 
type Props = {
  children: ReactNode
}
 
export const Example: FC<Props> = memo((props) => {
  const { children } = props
 
  return <div>{children}</div>
})

終わりに

今回は、サーバーコンポーネントとクライアントコンポーネントについて簡単に説明させてもらいました!
この記事で少しでもサーバーコンポーネントを理解してもらえたら嬉しいです!

この記事を書いた人

塩見直樹
塩見直樹

TOKOSのバックエンドエンジニア。パフォーマンス最適化と可読性の向上を目指しています。アニメ好きで、特にHUNTER×HUNTERが好きです。