Next.js(App Router)初心者が、Server/Client と CSR/SSR/SSG/ISR を手を動かして理解した話

Next.js(App Router)初心者が、Server/Client と CSR/SSR/SSG/ISR を手を動かして理解した話

はじめに

React は普段書いているけれど、Next.js はほぼ未経験。
そこで今回は、最小TODOアプリを作りながら次を理解することを目標にしました。

  • Server Component / Client Component の違い
  • CSR / SSR / SSG / ISR の違い
  • 状態管理ライブラリ(Zustand)の最小導入

「動いた」で終わらせず、なぜそう動くかまで言語化することを意識しました。

作ったもの(最小構成)

  • app/todos/page.tsx
  • app/components/TodoForm.tsx
  • app/components/TodoList.tsx
  • app/components/TodosClient.tsx
  • app/components/useTodoStore.ts

ポイントは、page.tsx を Server Component のままにして、状態管理と操作を TodosClient に寄せたことです。

Server/Client と CSR/SSR/SSG/ISR は別の話

最初に混乱したのはここでした。結論は次です。

  • Server/Client Component
    • 「どこでコンポーネントを実行するか」の話
  • CSR/SSR/SSG/ISR
    • 「ページをいつ生成するか」の話

つまり、同じ概念ではないです。

page.tsx でレンダリング方式を実験

renderedAt(サーバ描画時刻)を表示して挙動を確認しました。

SSG(静的)

export const dynamic = "force-static";
  • npm run build && npm run start
  • リロードしても renderedAt が固定
  • 結論: ビルド時に生成されたHTMLを配信

SSR(動的)

export const dynamic = "force-dynamic";
  • リロードごとに renderedAt が変わる
  • 結論: 毎リクエストでサーバレンダリング

ISR(間隔更新)

export const revalidate = 60;
  • 60秒以内は同じ表示
  • 60秒超過後のアクセスで再生成
  • 結論: 静的配信ベースで定期更新

なぜ build + start で確認したのか

  • npm run dev は開発体験(HMR)優先
  • npm run build は本番成果物を作る
  • npm run start は成果物を本番モードで配信する

レンダリング方式の差分確認は、本番モードが正確でした。

ライフサイクル理解(関数とクラス)

比較用に2ページを作りました。

  • /class-sample(クラス)
  • /function-sample(関数)
    確認したこと:
  • mount: 初回表示
  • update: state/props更新
  • unmount: 画面から消える

関数コンポーネントでは useEffect の cleanup を使います。

useEffect(() => {
  console.log("mounted");
  return () => {
    console.log("unmounted");
  };
}, []);

cleanup は「後片付け」です。イベント解除やタイマー停止をしないと、バグやリークの原因になります。

Zustand を入れて感じたこと

最小導入ではかなり分かりやすかったです。

export const useTodoStore = create<TodoState>((set) => ({
  todos: initialTodos,
  addTodo: (title) =>
    set((state) => ({
      todos: [...state.todos, { id: Date.now(), title }],
    })),
  deleteTodo: (id) =>
    set((state) => ({
      todos: state.todos.filter((todo) => todo.id !== id),
    })),
}));

set で状態更新
追加は「配列を増やす」
削除は「配列を絞る」

Redux Toolkitより、最初の体験としてはZustandの方が速く理解できました。

CSR / SSR / SSG / ISR を要件で選ぶ基準

CSR

操作が多いUI、管理画面向き

SSR

常に最新性が必要なページ向き

SSG

更新頻度が低く、速度重視のページ向き

ISR

速度と鮮度のバランスを取りたいページ向き

一言まとめ: 鮮度重視=SSR、速度/コスト重視=SSG、中間バランス=ISR。

まとめ

Next.js は「Reactを書く」だけでなく、表示責務(Server/Client)と生成タイミング(SSR/SSG/ISR)を設計するフレームワークだった
renderedAt のような観測ポイントを置くと理解が深まる
小さく作って、構造を読んで、少し触る進め方が最も効率的だった
次は、この構成を保ったまま fetch を追加して、キャッシュ戦略まで学習したいと思います。

コメント

タイトルとURLをコピーしました