Open14
Learn | Next.js
Hydration
サーバーからHTMLが返却される時点で静的な部分はあらかじめ生成されいて、クライアント側でそのHTMLに対してイベントリスナ等インタラクティブな機能を登録する。
ランダム値などを描画する必要があるコンポーネントでは、サーバー側で生成されるHTMLとクライアント側が期待するHTMLに乖離が発生してクライアント側でうまく処理できないケースが発生する。(Hrdration error
)
→対処法として、初期値はnull
を設定し、動的になる箇所はuseEffect
を利用しクライアント側で対応。※useEffect
はクライアントでのみ(hydration後に)実行される
Chapter4
-
app
ディレクトリにディレクトリをネストさせ、作成したディレクトリ配下にpage.tsx
を配置していくことでルーティングを実現する。(file-system routing) - 各ディレクトリにはレイアウトコンポーネント(
layout.tsx
)を配置することができ、ディレクトリ毎に違うレイアウトを実現できる- ネストしたディレクトリにレイアウトコンポーネントを配置しない場合は親ディレクトリのレイアウトコンポーネントが適用される
※この場合、ページ遷移があってもchildren
のみレンダリングされてレイアウトの再レンダリングは行われない
- ネストしたディレクトリにレイアウトコンポーネントを配置しない場合は親ディレクトリのレイアウトコンポーネントが適用される
-
RootLayout
は必須で必要であり、RootLayout
に追加したUIは全ページに適用される
Chapter5
- a要素による遷移ではページ全体が再レンダリングされる
- 最適化を行う(ページ全体の再レンダリングを防ぐ)為に
Link
(next/link)を使用する
- 最適化を行う(ページ全体の再レンダリングを防ぐ)為に
- Next.jsは(route segmentsによる)自動コード分割を行う → 各ページは独立した状態となる
- 初期ロード時にアプリ全体をロードするこれまでのReact SPAとは異なる仕組み
-
Link
コンポーネントがviewportに出現するとバックグランドで自動的にリンク先のデータをprefetch
する → ユーザーがクリックするタイミングでは遷移先のページは既にロード済みの状態を実現する
Chapter7 (Fetching Data)
- NextjsではAPIを構築する為にRoute Handlerを使用する
- Server componentsは
promise
をサポート - Server componentsはサーバー上でDB問い合わせが可能な為、APIレイヤーの実装を省略できる
- サーバー上でDB問い合わせが可能な為、膨大なデータを取得してクライアント側でデータ整形(ソート等)する必要が無くなりパフォーマンスアップに繋がる
-
Request waterfall
を回避したい場合はPromise.all
を使用
Chapter8 (Static n Dynamic Rendering)
-
Dynamic Rendering
: リクエスト時にサーバー上でコンテンツをレンダリングする。リクエストユーザー毎に最適化された情報を表示したり、新鮮なデータ(リアルタイムデータ)を提供するケース等に必要。 - 一部のリクエストが遅い場合、初期表示でページ全体のブロックしてしまいUX悪化に繋がるので注意
Chapter9 (Streaming)
-
任意のルーティングディレクトリ配下に
loading.tsx
を置くことでページコンテンツのローディング中のローディング画面を実現できる(ページ全体) -
静的コンテンツ(ex. サイドメニュー)は表示されるのでユーザーは動的コンテンツのローディング中も画面操作可能
-
loading.tsx
を配置したディレクトリ配下全体のページにローディングのUIが適用される → Route Groupsで制御する- これによってサイドメニュー等の静的な部分のLayoutは優先して表示しつつ、データのレスポンスを待つ必要のある
page
コンポーネント部分にのみローディング画面を表示できる
app/dashboard ├── (overview) ← Route Groups │ ├── loading.tsx │ └── page.tsx ├── customers │ └── page.tsx ├── invoices │ └── page.tsx └── layout.tsx
- これによってサイドメニュー等の静的な部分のLayoutは優先して表示しつつ、データのレスポンスを待つ必要のある
-
並列でデータフェッチングしている場合(
Promise.all
)はそれらのデータに依存するコンポーネントをグルーピングしたコンポーネントを作成し、wrapperとなるコンポーネントをSuspense
でラップすることで静的なUIの初期表示を早くする -
Suspense
コンポーネントをどこに配置するかはシチュエーションによって決定する- 一般的なベストプラクティスはデータフェッチング処理が必要な箇所をコンポーネント化し、そのコンポーネントを
Suspense
でラップする
- 一般的なベストプラクティスはデータフェッチング処理が必要な箇所をコンポーネント化し、そのコンポーネントを
Chapter10 (Partial Prerendering *experimental feature)
- 通常、内部で
dynamic function
(ex.noStore()
,cookies()
)を実行する場合、そのルーティングは全体がdynamicになる -
Partial Prerendering
を試すための設定
Chapter11 (Adding Search and Pagination)
URL search paramsを使う理由
- bookmarkable n Shareable URLs
- SSR n Initial Load
- Analytics n Tracking
-
URLSearchParams
はURLのクエリパラメータを操作する為の汎用メソッドを提供するWeb API -
input
要素に指定するvalue
vsdefaultValue
- クエリパラメータを自身でstate管理している場合は
value
を使用(controlled component
として扱う為)
- クエリパラメータを自身でstate管理している場合は
- 検索のような機能でキー入力の度にリクエストが送られると、サービスの規模感によってはサーバー負荷が大きくなるので
debouncing
を行い最適化を行うとよい
→use-debounce
パッケージを利用可能 -
userSearchParams()
hookとserchParams
propの使い分け- 一般的に
client component
でclientからの入力を受け付けたい場合はhook
、client compoentで取得した値をpropとしてserver component
に渡すような使い分け
- 一般的に
Chapter12 (Mutating Data)
Server Actionsについて
-
Server Actions
はサーバーで非同期処理を実行可能にする仕組み
→ API endpointsを作成する手間なしに、データ操作を行うことが可能になる - 以下の技術でセキュリティ強化を実現
- POSTリクエスト
- 暗号化されたclosures
- strict入力チェック
- エラーメッセージのハッシュ化
- host制限
- Reactでは
form
要素のaction
属性は特別なpropとして扱われhandler(ここがserver action
になる)を渡すことができる。※そのため通常のHTMLのaction
にURLを指定する考え方とは異なる - Server Actionへエンコードされた値を渡す為に
bind
を使用
Chapter13 (Handling Errors)
- route segmentに
error.tsx
を配置することで、全てのerrorをcatchしfallback UIを表示可能 -
error.tsx
はclient component
である必要がある -
error
コンポーネントはJSのError
オブジェクトとエラーをリセットするための関数であるreset
の2つのpropsを受け付ける-
reset
はroute segmentを再レンダリングする関数
-
- リソースが存在しない場合は
next/navigation
のnotFound()
を使用することで、errorをthrow可能- route segmentに
not-found.tsx
を配置してthrowされたerrorを検知し404画面表示
- route segmentに
Chapter14 (Improving a11y)
-
zod
のバリデーションルールでcoerce
を使うと後続の型を強制できる-
z.coerce.number()
ならstringがnumberとして扱われて未入力の場合は値が0になる
-
Chapter15 (Adding Authentication)
前提:NextAuth
を使用 ※beta版
-
auth.config.ts
で設定を行うことができる
ex.NextAuthが提供しているログイン画面ではなく自身が用意したログイン画面を使用したい場合は、authConfig
のpages
プロパティに{signIn: '/login'}
を設定 -
callbacks
に設定したauthorized
メソッドはリクエストが完了する前に実行される - middlewareが認証状態の検証を終えるまで画面のレンダリングはスタートしない → セキュリティとパフォーマンスの向上に繋がる
- NextAuthの
Credentials
プロバイダーはユーザー名とパスワードによるログインを許容
Chapter16 (Adding Metadata)
-
app
ディレクトリ配下にfavicon.ico
やopengraph-image.jpg
と命名されたファイルを配置することでファイルベースでMetadataを設定可能(File-based
) - 各
layout.tsx
やpage.tsx
でmetadata
オブジェクトをexportすることでMetadataを設定することも可能(Config-based
) - 各ページ固有の情報に加えて固定の情報も設定したい場合は、
template
フィールドを設定