Nextjs

Next.jsのルーティングのファイル名規則【Next.jsのAPPルーターを使おう 第四回】

Next.jsのAppルーターでルーティングする際のファイル名規則について。

以下の記事の続き。基本的なことは以下で。

Next.jsのルーティングの基礎の基礎の基礎【Next.jsのAPPルーターを使おう 第三回】
Next.js13.4から正式実装になったApp Routerを使うためのメモ。 第三回はルーティングの基礎、の基礎の基礎。 詳細は以下の公式で。 基本的には公式ページを読んでもらえればわかること。 App ...

Next.jsのAppルーターではルーティング対象になるファイル名があらかじめ予約されていて、それらには意味がある。

各名称ごとに役割があり、かつ、特定の順番で階層化される。

各ファイル名の意味

  • page ⇒ フォルダの中に作ることでルーティングされてページが表示される。基本の基本の基本。
  • layout ⇒ childrenの中にpageの内容が入る。同じルート配下の子は全て親のレイアウトにネストされる。
  • template ⇒ 同一ルート内で遷移した時に再レンダリングするレイアウト。layoutは再レンダリングされない。
  • error ⇒ エラー処理。React Error Boundaryで自動でラップされる
  • global-error ⇒ errorのグローバル版。
  • loading ⇒ ReactのSuspenseを使う機能
  • not-found ⇒ 存在しないURLにアクセスがあった時の処理
  • route ⇒ APIエンドポイント
  • default ⇒ 何に使うか不明

page

Routing: Pages and Layouts | Next.js
Create your first page and shared layout with the App Router.

基本の基本になるのがpage。

フォルダの中にpageファイルを作ることで、ページが表示される。

pageが無いとルーティングされない。

app直下に作ったpageがトップページになる。

pageは基本的に「サーバーコンポーネント」になる。

pageではfetchを使ってデータ取得できる。

同一階層と先祖階層のlayout、template、error、loadingにネストされる。

layout

Routing: Pages and Layouts | Next.js
Create your first page and shared layout with the App Router.

複数ページで共有されるUIを設定するところ。

childrenが必要。childrenの中に、pageの内容が入る。

layoutはネストされるので、ルートの下全てに反映されるので、app直下に作ったlayout(ルートレイアウト)は全ページに反映される。

ルートレイアウトは必須。ルートレイアウトにhtmlbodyが必要。

ルートグループを使うことで、ルートレイアウトを複数作ったり、ネストしない形にすることもできる。

Routing: Route Groups | Next.js
Route Groups can be used to partition your Next.js application into different sections.

レイアウトは基本はサーバーコンポーネントになる。

pageと同様に、fetchでデータ取得できる。

レイアウト間ではデータのやり取りができないので、各レイアウトで個別にfetchする必要がある。

templates

Routing: Pages and Layouts | Next.js
Create your first page and shared layout with the App Router.

この機能はまだ実際に試していないのでわからないが、テキストを読む限りでは同一ルート内で遷移した時に再レンダリングするレイアウト、らしい。レイアウトは再レンダリングされないらしい。

基本的にはレイアウトと同じで、再レンダリングの有無が大きな違いっぽい。

next/linkとの関係性とか良くわからない。

next/linkを使うとuseEffectが起動しなくて再レンダリングできないのだけど、以下の例のようにすると動く。

Functions: usePathname | Next.js
API Reference for the usePathname hook.

templates内に書けば、これが無くてもnext/linkで再レンダリングされるのかどうかは知らない。

templatesの機能はテキストを読むだけだと、細かい挙動が想像できない。今後の課題。

errorとglobal-error

Routing: Error Handling | Next.js
Handle runtime errors by automatically wrapping route segments and their nested children in a React Error Boundary.
File Conventions: error.js | Next.js
API reference for the error.js special file.

errorは、React Error Boundaryで自動的にラップしてくれるファイル。

階層ごとに作れるので、エラーを切り分けて、エラー用の表示と解決策を設定することができる。

ルートコンポーネントに対してエラー処理する場合はglobal-errorを作る必要がある。

errorはクライアントコンポーネントになるので、'use client'表記する。

クライアント側への機密情報漏洩を避けるために、サーバーコンポーネントでエラーがあった場合、特定のエラーの詳細が削除される。

同一階層だとレイアウト内にネストされるので、レイアウトに対してのエラー処理をしたい場合は、対象のレイアウトの親階層に入れる必要がある。

loading

Routing: Loading UI and Streaming | Next.js
Built on top of Suspense, Loading UI allows you to create a fallback for specific route segments, and automatically stream content as it becomes ready.

ReactのSuspenseを差し込んでくれるのがloading。

Suspenseはロード中のアニメーションなどで使われるあれ。

コンポーネントのロードに時間がかかる場合に、「コンポーネントがローディング中なので今はレンダリングできないよ」という状態にしておけて、ロードするまでの間に別のURを表示しておける、というもの。


<Suspense fallback={<div>ロード中はここが表示される</div>}>
  {/* 通常はここが表示される */}
  <MyComponent />
</Suspense>

Next.jsでloadingを作ると、Suspenseのfallbackにloadingが設定される。

not-found

File Conventions: not-found.js | Next.js
API reference for the not-found.js file.

存在しないURLにアクセスした時に表示されるページを作ることができる。要は404ページみたいなもの。

v13.3以降はapp直下に置けばサイト全体の404ページとして機能する。v14では一応想定通りに動いている。

ただし、generateStaticParamsのdynamicParamsの設定や、error.tsの設定と競合する。各種設定や、not-foundがどの階層に置いてあるかで挙動が変わるので注意か必要。

route

Routing: Route Handlers | Next.js
Create custom request handlers for a given route using the Web's Request and Response APIs.

APIが作れる。

具体的な例は以下。

Next.jsでローカルで動くAPIをルートハンドラーで作る【Next.jsのAPPルーターを使おう】
Next.jsのpagesルーターでは、APIルートが準備されている。pagesフォルダの配下にapiというフォルダを作り、その中にAPIを作ることができた。 Appルーターでは少し作り方が変わっている。 以下はAppル...

default

Next.js公式には、ドキュメントページはあるけど中身はまだないため、何のためにあるのかよくわからない。

File Conventions: default.js | Next.js
API Reference for the default.js file.

階層の順番

各ページは基本的にコンポーネントととして階層化されてレンダリングされる。

以下の順番。


<Layout>
  <Template>
    <ErrprBoundry fallback={<Error />}>
      <Suspense fallback={<Loading />}>
        <Page />
      </Suspense>
    </ErrprBoundry>
  </Template>
</Layout>

各種コンポーネントはネストされる。

以下のようなフォルダ構成の場合。


   └─ test1
       ├─ layout.tsx
       ├─ error.tsx
       ├─ loading.tsx
       └─ test2
           ├─ layout.tsx
           ├─ error.tsx
           ├─ error.tsx
           ├─ loading.tsx
           └─ page.tsx 

以下のようにネストされる。


<Layout>
  <ErrprBoundry fallback={<Error />}>
    <Suspense fallback={<Loading />}>
      <Layout>
        <ErrprBoundry fallback={<Error />}>
          <Suspense fallback={<Loading />}>
            <Page />
          </Suspense>
        </ErrprBoundry>
      </Layout>
    </Suspense>
  </ErrprBoundry>
</Layout>

まとめ

pagesルーターでは好きに名前が使えてルーティングされるときのURLになったのだけど、Appルーターではpageが入っているフォルダ名がURLになった。

Next.jsで予約されている名前もあるため、ルーティングされない部分はプライベートフォルダを使うのがわかりやすそう。

layoutは便利だけど、他のフレームワークにあるslot的な機能はないため、ちょっと使いにくい。共通のコンポーネントを配置する場所、という位置づけのほうが良さそうな気がする。日本語の意味でのレイアウトとして使おうとすると、slotが欲しくなる。

v14時点では、not-foundとerrorは同一階層に置いておくと、errorのほうが優先されるみたいで、他の機能とどう競合するのかいまいちよくわからない部分がある。

loadingはReactのSuspenseを手軽に使えそうで便利。

templatesをまだ試せてないのが、今後の課題。

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