目次
- はじめに
- そもそもNext.jsとは
- App Routerについて
3-1. まず従来のPages Routerとは
3-2. App Routerの特徴やメリット- ルーティングの方法
- レイアウトをネストできる
- デフォルトでReact Server Componentとなる
- データ取得処理がシンプルになった
- 終わりに
1. はじめに
本記事のゴール
Next.jsの勉強を始めましたが、基本的な理解がまだ足りていないと感じるので、まずはApp Routerの特徴について、ある程度説明できるようになることをゴールにしています。
筆者のスキルレベル
- React含めて実務経験は0
- Next.jsのチュートリアルは一通り行った程度です(1から書くのはまだ難しい)
(本記事を書くにあたり、こちらの記事に沿ってチャットアプリを作成したり、
こちらのUdemyを一通り実施した)
2. そもそもNext.jsとは
- Reactをベースにしたフレームワーク
- その上で、ルーティングやSSR(サーバーサイドレンダリング)などReactではカバーできない範囲も含めアプリケーション開発に必要な機能を備えています
- State of JavaScript 2023では一番使用率が高く、その人気が分かります
(画像引用: https://www.publickey1.jp/blog/24/state_of_javascript_20231reactnextjs23500.html)
2-1. ちなみにフレームワークとは
- アプリ開発でよく利用される機能があらかじめ揃えられたもの。実装に必要な骨組みがすでにできているイメージです。
- 基本的な機能が揃っているので、実装の負担を減らすことができます
ライブラリとの違い
ライブラリはあくまで機能、つまり部品のみが集まっているイメージです。
ReactやjQueryなどがライブラリにあたります。
対してフレームワークは骨組みも備えているイメージです。
フレームワークはすでに必要な機能が揃っている分、実装面の自由度は低くなるのがデメリットだが、ライブラリはその逆で、必要な機能だけ持ってこれるので実装の自由度は高くなります。
2-2. Reactと比べた際のNext.jsのメリット(一例)
クライアント環境に依存しないレンダリング
Reactはクライアント側でレンダリングを行うが、ページ数が多いサイトを閲覧する際や、ユーザー環境によっては初回読み込み速度が遅くなる可能性があります。
対してNext.jsが基本サーバー側でレンダリングするので、上記理由によってユーザビリティを損ないません。
ルーティング設計を直感的に行える
React単体にはルーティング機能(= 特定のURLが指定された時に、どのファイルを実行するか決定する)はなく、React-Routerのような別のライブラリが必要になります。
Next.jsではapp
(13.xより前はpages
)ディレクトリにファイルを配置すると、URLとファイルを自動的に紐付けてくれます。
※App Router とPages Routerに関しては後述
上記以外にもSEOの改善など、Reactでは対応できない機能を備えています。
3.App Routerについて
3-1. まず従来のPages Routerとは
デフォルトでsrc/pages
ディレクトリが用意されており、配下に作成したファイル名がそのままURLとして適用されるので分かりやすい。
下記blogのように、pages
配下でネストしても、同じくそのフォルダ名がURLに適用される。
pages
┗ index.tsx // → / でアクセス可能
┗ blog
┗ articles.tsx // → blog/articles でアクセス可能
3-2. App Routerの特徴やメリット
Next.js13からリリースされた機能。
13.4から安定版となりました。
ちなみにcreate-next-app
でプロジェクトを作成した場合、App Routerを使用するか聞かれるので、Yesと答えると適用される。(Noにすると従来のPages Routerの構成になる)
Pages Routerとの主な違いは下記。
3-2-1. ルーティングの方法
-
pages
ではなく、app
ディレクトリに名称変更された - Pages Routerでは
pages
配下に作成したファイルがそのままルーティングされていたが、page.tsx(js / jsxファイルでもOK)
というファイル名にした場合のみルーティング対象となり、ブラウザ上で確認することができる
app
┗ index.tsx // → pageの名称ではないので404になる
┗ page.tsx // → / でアクセス可能
┗ blog
┗ articles.tsx // → pageの名称ではないので404になる
┗ page.tsx // → blog/ でアクセス可能
3-2-1-1. ルーティングの方法が変わったことによるメリット
ルーティングしたいファイルか否かで分けることができる
前述の通り、Pages Routerでは全てのファイルがルーティングの対象になっていました。
ただ実装していると、ルーティングの対象にする必要がないファイルもでてきます。
例えば今回作成したチャットアプリでは、チャット内容を表示する吹き出しを下記のようにpost-item.tsx
componentとして実装していました。
app
┗ components
┗ post
┗ post-item.tsx // components/post/post-itemにアクセスしても404となる
Pages Routerの場合、このファイルにもURLでアクセスできてしまいますが、App Routerだと不必要にルーティングに影響しません。
つまりルーティングしたい場合と、それ以外(レイアウトにのみ使用したい場合など)で役割でファイルを明確に分けることができます
3-2-2. レイアウトをネストできる
ヘッダーなど、ページ共通で表示したいパーツはlayout.tsx
に記載することで表示することができます。
更に新規でディレクトリ追加(下記ではtest
) & test/layout.tsx
を追加した時、test/page.tsx
ではルートのlayout.tsx
を継承した状態でtest/layout.tsx
が表示されます。
app
┗ layout.tsx
┗ test
┗ layout.tsx // ルートのlayout.tsxの中に、更に`test/layout.tsx`が表示される
┗ page.tsx
3-2-3. デフォルトでServer Componentとなる
従来のPages Routerでは作成したcomponentがデフォルトでCSRとなる。簡単にいうとコンポーネントに記載したjsがクライアントで実行されていました、
App RouterではデフォルトでServer Component(以下SC)となります。
SCによって、以下のようなメリットが生まれました。
- 各componentの役割(サーバー or クライアントのどちらで実行したいか)が明確になるので保守性が向上する
- 従来jsはクライアント側で実行されていたが、サーバーで実行できることにより無駄にクライアント側へjsが送信されるのを防ぐ etc
もしApp RouterでClient Componentにしたい場合は、ファイル1行目に下記のように'use client'
と記載します。
'use client'
const Hoge = () => {
return (
<div>
</div>
)
}
SCの使い分け
現状の自分の理解では、下記のようなパターンではclient componentにし、
それ以外では基本SCのままで実装するイメージです。
- 質問内容の送信処理など、イベントハンドラを付与したい時
- useEffectやuseStateを使用したい時
3-2-4. データ取得処理がシンプルになった
まず前提として、2-2-3で触れたCSR以外に、next.jsには下記3種類のレンダリング方法があります。
- Static Site Generator(SSG)
- Server Side Rendering (SSR)
- Incremental Static Regeneration (ISR)
▼各レンダリングの特徴は公式を参考にいただけると幸いですmm
3-2-4-1. getStaticPropsやgetServerSidePropsが不要になった
Pages RouterではgetStaticProps
やgetServerSideProps
を使用して上記レンダリング方法を指定する必要がありました。
対してApp RouterではgetStaticProps
やgetServerSideProps
は無くなり、下記のようにfetchに引数を与えることでシンプルに指定することができます。
// SSG
// ※SSGは初期値なのでわざわざ下記を記述する必要はありません。
const res = await fetch(URL, { cache: ‘force-cache' });
// SSR
const res = await fetch(URL, { cache: 'no-store'});
// ISR
const res = await fetch(URL, { next: { revalidate: 10 } }));
3-2-4-2. SSGやSSRが同一ページのコンポーネントで併用できるようになった
Pages Routerではデータの取得タイミングがページ単位で決められていました。
例えばgetStaticPropsを使用したページはビルド時にデータを取得することになり、
getServerSidePropsを当該ページのコンポーネントで併用することはできません。
対してApp Routerでは同一ページ内でもSSGやSSRを併用することができます。
まとめ
初学者的に感じたApp Routerの特徴やメリットをざっくりとですがまとめてみました。
個人的にはgetStaticPropsやgetServerSidePropsが無くなり、fetchで制御できるようになったことなど、App Routerの方がよりシンプルかつ分かりやすくなった印象です。
今後の制作でも、これらの特徴を理解した上で効果的にApp Routerを導入していきたいと思います。
参考