「実践Next.js App Routerで進化するWEBアプリ開発」アウトプットメモ
内容
「実践Next.js App Routerで進化するWEBアプリ開発」を読み、要点やそこから発展して調べたこと、感想などをメモしてアウトプットする。
1回読み、必要そうであれば(必要なところだけでも)もう一度読み、新たな発見や感想があればメモする。
あくまで自分が理解するためのアウトプットなので、きれいに書く必要はないが、人に説明する(読んでもらう)つもりで書く。
この本を読む動機
- インターン先での勉強会をこの本を使って進めることになった
- 個人開発をする際にNext.jsを使いたいが、知識が浅いと感じている
- 今後インターンでNext.jsを使用するなら学んでおきたい
目的
本の内容を理解すること。読み切ることではない。
第1章
以下コマンドでプロジェクトの雛形生成。
npx create-next-app
ルーティング
App Routerではappディレクトリ内にルーティングで遷移させたいディレクトリをおく。
appディレクトリ内の各ディレクトリそれぞれに配置されたpage.tsxでコンテンツを定義する。
page.tsxの例
export default function HomePage() {
return (
<div>
<h1>HOMEPage</h1>
</div>
);
}
export defaultされたコンポーネントが1つのページになる(index.htmlのようなイメージ)
appディレクトリにlayout.tsxをおく。
各ページで共有されるスタイルやコンポーネントを定義する。
appは以下の各ディレクトリにもおける。
export default function RootLayout(
{ children, }: { children.React.Node; }) {
return (
<html lang="ja">
<div>
<Header />
<div>
<main>{children}</main>
</div>
</div>
</html>
);
}
各ページで共有される<Header />が定義され、childrenを子セグメントとして定義している。
セグメメント(rootより下のディレクトリ)ではpage.tsxまたはlayout.tsxどちらかだけでも成立する。
SPAでのナビゲーション
Next.jsではSPAを提供している。
SPAとは?
MPA(マルチページアプリケーション)←→SPA(シングルページアプリケーション)
MPAは…
- サーバー側でHTMLを生成
- ページ遷移で情報更新
SPAは…
- クライアント側でHTMLを生成 (初回読み込み時等は違う)
- ページ遷移時に変化した部分のみ更新(リロードなしで画面遷移できる)
- 1度取得した情報をキャッシュとして活用できる
SPAではページ全体を再読み込みしなくていいので高速!
<Link>コンポーネントはhtmlでいうaタグだが、クリックされると画面の再読み込みなしで遷移する。
useRouter(router.pushやrouter.back)を使用してもLinkタグのように画面の再読み込みなしで遷移する。
Q: Next.jsはSPA→クライアント側でレンダリングするの?
AppRouterはデフォルトでReact Server Components (RSC)が適用され、基本的サーバー側でレンダリングが行われる。Next.jsがSPAなら、レンダリングはクライアント側で行われるのではないのか?
→Next.jsはSPAを提供しているが、App RouterはSPAそのままではなく、サーバーサイドレンダリングの利点(初期ロードの速さ、SEOの改善)とSPAの利点(高速なページ遷移、動的なUI更新)を組み合わせているイメージで、サーバーサイドでレンダリングしつつもページ遷移時に変化した部分のみ更新することでレンダリング範囲を減らしているということかも
→聞いてみた
上記の認識で合っている。最初はサーバーサイドでレンダリングし、クライアントにHTMLが返る。その後は更新があったところだけサーバー側で更新。
サーバー側でできるレンダリングはサーバー側でする。
ネスト可能なレイアウト
layout.tsxは子に継承されるので、「このサブツリー(ルートの子ディレクトリ)はみんな同じUI」ができる。
第2章
App RouterではServerComponentが使われている。
React Server ComponentとClient Componentを組み合わせる
App RouterではServer ComponentとClient Conponentを組み合わせて使い分け、機能を実装する。
App Router内のコンポーネントのデフォルトは、ServerComponentだが、'use client'の宣言をして書くことで、Client Conponentを実装できる。('use client'の宣言をすると、そのファイルのサブツリーも全てClient Conponentになる)
Server ComponentとClient Componentを組み合わせることで、ブラウザに送るJava Scriptを最小限に抑えてパフォーマンス効率を高められる。
Client Componentの宣言は最小限にとどめた方が良い。
Server Componentとは
従来のReactのサーバーサイドレンダリングのコンポーネントは…
- 全てブラウザとサーバー両方で実行される。
- 同期関数しか使えない
- ハイドレーションできる
Server Componentは…
- サーバーサイドでのみ実行されるコンポーネント。
- 非同期関数が使える(→コンポーネント上で直接APIデータを取得したりできる!)
- ハイドレーションできない(ブラウザで実行すべきJava Scriptを付けられない)
サーバーサイドレンダリング(SSR)とは
サーバーサイドレンダリング(SSR)
- サーバー上で動的にレンダリングしてできたページをクライアントのブラウザに送信する。
クライアントサイドレンダリング(CSR)
- 最小限の HTMLのみがクライアントに送信され、レンダリングや更新などはクライアント側でJavaScriptを使って行われる
ハイドレーションとは
「ボタンをクリックしたら処理を行う」のような、操作に対してブラウザとサーバーが双方向に反応する機能を実装するために、ブラウザで実行されるJava Scriptをつける、その一連の流れのこと。
例:ボタンをクリックしたら処理を行うためには、ボタンをのDOM(HTMLを操作するAPI)にonClickイベントハンドラーを当てはめることで動作するようになる。←この流れをハイドレーションという
Client Componentとは
ブラウザとサーバー両方で実行されるコンポーネント。
ハイドレーションできる(ブラウザで実行すべきJava Scriptを付けられる)。
Server ComponentとClient Componentの使い分け
Server Componentを使うケース
- 非同期処理を使いたい時(データ取得など)
- バックエンドから何かを持ってくる時
- 機密情報を扱うとき
など
Client Componentを使うケース - ハイドレーションしたい時(ボタンなどブラウザとサーバーが双方向に反応する機能を実装したい時)
- コンポーネントが持っている状態を扱う時
- ブラウザ専用のAPIやHooksを使う時
など
動的データと静的データの取得方法の違い
- 動的データ→頻繁に更新される値。
閲覧履歴・ログインユーザー情報・商品在庫数など。 - 静的データ→頻繁に更新されない値。
商品概要・ブログ記事など。
Next.jsのデータ取得関数fetchは、デフォルトでは静的データ取得として扱い、結果をキャッシュする。
動的データとして扱いたい場合は{ cache: "no-store" }のように指定する必要がある。
キャッシュされている場合、一度取得したデータを保持し、APIサーバーへのリクエストは発生しない。
(ビルド時やユーザーがページにアクセスした時に加え、next: { revalidate: 60 } のように設定することで、指定した時間が経過するごとにキャッシュが更新されるようにできる。)
第3章
Next.jsにはファイル名・フォルダ名・変数名などに規約がある。