Next.js - React Essentials
Server Components
- レンダリングされる場所をサーバ側に固定できるようになった
- Client Components (及びこれまでの Pages Router)
- pre-rendering & hydration で動作する。つまりどちらサイドでも描写される可能性がある。
- 依然として JavaScript が必要
- Server Components
- サーバーサイドでのみレンダリングされる
- クライアントサイドでレンダリングされることはない
- JavaScript は完全に必要ない
- Client Components (及びこれまでの Pages Router)
- Server Components にはレンダリングの種類が 2 つある
- Static Rendering
- ビルド時に確定するもの
- SSG, ISR と同じ
- キャッシュ可
- Dynamic Rendering
- リクエスト時に確定するもの
- SSR(
getServerSideProps()
)と同じ - キャッシュ不可
- Static Rendering
- メリット
- 速いデータ取得
- バンドルサイズの減少
- Ruby on Rails のような開発体験
- App Router ではコンポーネントはデフォルトで Server Components としてレンダリングされる
- 以下のファイル名は特別な役割を持つ
layout
page
loading
not-found
error
global-error
route
template
default
Client Components
- インタラクティブ性をもつコンポーネント
- pre-rendered & hydrated される
- 従前の Next.js の Pages Router と同じ
use client
directive- ファイルの先頭に書くと、Client Components としてレンダリングされる
- Server のみでレンダリングするものと、Client でもレンダリングするものの境界を規定する
- 配下のコンポーネントはすべて Client Components としてレンダリングされるようになる
使い分け
- 以下を行う場合は Server Component が最適
- データ取得
- バックエンドへのアクセス
- Access Token などの機密情報を扱う
- 大容量の依存ライブラリを使う
- 以下を行う場合は Client Component が最適
- onClick, onChange 等のインタラクティブ性が必要
- useState, useEffect などのライフサイクルエフェクトが必要
- ブラウザ固有の API を使う
- カスタムフックを使う
- Class Component を使う
よくあるパターン
Client Component を葉に追いやる
そうすることで、Server Component の担当できる領域を増やしていく
Client Component と Server Component を組み合わせて使う
- サーバーではすべての Server Component が事前にレンダリングされて Client に送られる
- Client Component 内で Server Component をインポートして使うことはできない
- より具体的には、祖先から子孫に下っていく過程で一つでも
use client
している箇所があれば、その配下では Server Component を使うことはできない
- より具体的には、祖先から子孫に下っていく過程で一つでも
- ただし、Composition の書き方をすれば、Client Component の中に Server Component をネストさせることはできる
const SomeServerComponent = () => {
return (
<ExampleClientComponent>
<ExampleServerComponent />
</ExampleClientComponent>
);
};
Client Component に props を渡す
- Server Component から Client Component に props を渡すときには Serializable な値しか渡せない
- e.g. コールバック関数を与えることはできない
- なぜならそこにネットワークによる境界(断絶)があるため
- App Router では、Server Component と Client Component の間に境界がある
- Pages Router では、
get***Props
と Page Component の間に境界がある