見出し画像

Next.jsのApp Router理解してきた

昔少しだけPages Router時代にNext.jsを触っていたのですが、久しぶりに使ってみるとApp Routerなるものを公式からお薦めされたので遊びでシステムを作りがてら少し学んでみました。


Pages Routerとの違い

概要

ルールが少し複雑になった代わりに、今まで絶妙に実現が難しかったことが簡単にできる & コード的にも整理しやすくなったイメージ

※Pages Routerに詳しいかと言われるとそんなことないので、このくらいしか言えない

基本的なルーティング

Pages Routerは大雑把にこういうルール

↓みたいにフォルダ分けすると...

pagesindex.tsxfolder1
 ∟index.tsx
 ∟page1.tsxfolder2
 ∟page2.tsx
 ∟page3.tsx

こんなルートが出来上がる

  • example.com

  • example.com/folder1

  • example.com/folder1/page1

  • example.com/folder2/page2

  • example.com/folder2/page3

※「index.tsx」を作るとそのディレクトリのルートがルーティングされる

App Routerはこういうルール

apppage.tsxfolder1
 ∟page.tsx
 ∟folder2
  ∟page.tsxfolder3
 ∟folder4
  ∟page.tsx
 ∟folder5
  ∟page.tsx

これでこんなルートが出来上がる

  • example.com

  • example.com/folder1

  • example.com/folder1/folder2

  • example.com/folder3/folder4

  • example.com/folder3/folder5

※ルート指定は全てフォルダで表現し、「page」というファイルで内容を表現する

こんな感じです
ファイルがルーティングに絡んでこないので、ある意味シンプルですね

特別なファイル & フォルダ

特別なファイル

ざっとこんなものがあります(頻繁に使いそうなものだけ抜粋)

  • page

  • layout

  • template

  • route

1つずつ紹介します

page

前述した通り、ページ内容を記載するファイルです
例えば以下のような記述でページを作る

export default function Page({
  params,
  searchParams,
}: {
  params: { slug: string }
  searchParams: { [key: string]: string | string[] | undefined }
}) {
  return <h1>My Page</h1>
}

layout

そのルート以下の全てで共有されるUIです
例えば dashaord/layout.tsx に以下を記述すると、 ルート dashbord, dashbord/* に関してはこのレイアウトが適用されます

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return <section>{children}</section>
}

また、ルートのレイアウト(app直下のlayoutファイル)は特別で、
ここでだけ <html>, <body> が使えます

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

※ここでメタデータなどの指定をすることも可能

template

これはlayoutと似ているのですが、pageをラップするUIです
ただしlayoutとは違い、自分よりも下層のルートには影響しません

route

httpリクエストを受け取れる
以下のように記述する

export async function GET(request: Request) {}
 
export async function HEAD(request: Request) {}
 
export async function POST(request: Request) {}
 
export async function PUT(request: Request) {}
 
export async function DELETE(request: Request) {}
 
export async function PATCH(request: Request) {}

特別なフォルダ

こちらもよく使いそうなものだけ抜粋

  • folder

  • [folder]

  • [...folder]

  • (folder)

  • _ folder

folder

上述した通り、通常のルーティングをするために使用
もちろんネストもできる

[folder]

URLからパラメータを取得したいときに使う
例えば以下のようにフォルダを作ると

appfolder1
 ∟[id]
  ∟page.tsx

「id」に指定された部分をパラメータとして取得可能
URL例:
example.com/folder1/1001

export default function Page({ params }: { params: { id: string } }) {
  return <div>My Post: {params.id}</div>
}

[...folder]

[folder]と同じようにパラメータを取得できる
これは複数のパラメータを取得可能

appfolder1
 ∟[...params]
  ∟page.tsx

こんな感じで指定されたパラメータを配列で取得できる
URL例:
example.com/folder1/1001/345

(folder)

ルーティングには関係ないけど、グループ分けしたいときに使う

appfolder1
 ∟(group1)
  ∟folder2
   ∟page.tsx
 ∟(group2)
  ∟folder3
   ∟page.tsx
  ∟folder4
   ∟page.tsx

このようにフォルダを分けると
(*)はルーティングに影響を与えないので、このようなルートができます

  • example.com/folder1/folder2

  • example.com/folder1/folder3

  • example.com/folder1/folder4

_ folder

この中のフォルダ、ファイルは一切ルーティングに影響を与えません
コンポーネントフォルダなどを作るときに便利なんだと思っています

その他 覚えておくと良いこと

基本的にSSR

すべてのUIファイルが基本的にSSRとなりました。useState, useEffectなどのReact hookを使いたい場合はファイルの最上部に「'use client'」と記載する必要があります。

'use client'
 
import { useState } from 'react'
 
export default function Counter() {
  const [count, setCount] = useState(0)
 
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  )
}

エラーページなど定義可能

実は上述で紹介した特別なファイル以外にもいろいろありまして、not-foundやerrorページもカスタマイズできます。

おわり

以上、使わなさそうなところはだいぶ省いて記述してみました。
ここがわかりにくい!などありましたらコメントいただけると嬉しいです。修正するかはわかりませんが、、笑

少しでもApp Router?何だこれ!?となっている人の役に立てれば光栄です。よろしくお願いします。

参考資料
Next.js公式doc

この記事が気に入ったらサポートをしてみませんか?