Next.jsの魅力と基本的な使い方まとめ

おはこんばんちは、ちーずです。
アドベントカレンダー9日目は「Next.js」に関してです！

## :question: Next.js とは
Next.jsはVercel社が開発しているReact製フレームワーク。
2016年に登場し、Netflix、GitHub、Uberなど様々な大企業で利用されています。

## :muscle_tone2: Next.jsのここがすごい！

### SSG / SSR / ISRに対応！
`pages`ディレクトリ配下のファイルに設定を記載するだけでレンダリング方法を設定できます。

また、ページごとにレンダリング方法を設定できるため、
ページの特性に合わせてレンダリング方法を変えることができます。

### セッティング不要！
`create-next-app`コマンドを実行するだけで、すべてが自動的にセットアップされたNext.jsのアプリケーションが生成できます！
その他のアプリケーションの設定も、`next.config.js`ファイルを書き換えることで実現できます。

### 画像の自動で最適化！
Next.jsが提供しているImageタグを用いることで、最適化された画像が配信されます。
また、遅延ロードや画質の最適化なども設定することができます。

### ファイルベースルーティング
`pages`配下のディレクトリは、自動的にルーティングの設定がされます。
そのため、自らルーティングの設定をすることは不要です。

### API Routes
`pages/api`に配置されたファイルは、APIエンドポイントとして扱うことができます。

## :desktop: Next.jsのレンダリング / データフェッチの仕組みについて

SSR / SSG / ISR の仕組みに関しては下記記事で手書きの図解しているので参考にしてください！

https://qiita.com/cheez921/items/245860c839f7e3a15a69

この章では「Next.jsではどのように設定できるか」のお話しをします！


### SSR (Dynamic)
`SSR`の設定をするには、ページComponentにて**`getServerSideProps`**関数をexportします。
この設定を書くことで、**リクエスト時**に実行され、返却された`props`はページComponentで利用することが可能です。

```jsx
export async function getServerSideProps(context) {

  // データをフェッチする処理など

  return {
    props: {
      // ページComponentに渡したいデータ
    },
  }
}

```


### SSG (SG)
`SSG`の設定をするには、ページComponentにて**`getStaticProps`**関数をexportします。
この設定を書くことでで、**ビルド時**に実行され、返却された`props`はページComponentで利用することが可能です。

※ 先ほど紹介した`getServerSideProps`とは一緒に使うことができません。

```jsx
export async function getStaticProps(context) {

  // データをフェッチする処理など

  return {
    props: {
      // ページComponentに渡したいデータ
    },
  }
}
```

また、SSGを実現する際に、`getStaticProps`で取得したデータを使ってルーティングの設定をしたいケースがあります。([動的ルーティングに関して詳しくはこちら](#dynamic-routes)) 
その際には、**`getStaticPaths`**関数をexportします。

```jsx
export async function getStaticPaths() {
  return {
    paths: [
      { params: {} } 
    ],
    // boolean | 'blocking' 
    // false - 404ページ
　　　　　　　　// true - 事前にビルドしてない場合、フォールバック状態 → サーバーサイドで静的なファイルを生成し、返す
　　　　　　　　// blocking - 事前にビルドしてない場合、SSRde実行し生成されたHTMLを返す
    fallback: true 
  };
}

```

例えば、取得したブログ分`/blogs/{id}`というURLを作りたいとしましょう
下記コードを記載することで、ブログ分のURLを生成することができます。

1. `pages/blogs/[id].tsx`という動的ルーティングファイルを作成
2. `getStaticPaths`ブログに取得処理を追加
3. 取得したデータから、`{params: ブログのid }`の配列を生成し、返す


```pages/blogs/[id].tsx
export async function getStaticPaths() {
  // ブログのデータを取得する
  const res = await fetch('https://.../blogs')
  const blogs = await res.json()

  // 
  const paths = blogs.map((blog) => ({
    params: { id: blog.id },
  }))
  return { paths, fallback: false }
}

```

### ISR
`getStaticProps`のオプションに一行追加するだけで実装できます。

```diff_typescript
export async function getStaticProps(context) {
  return {
    props: {},
+   // 何秒に1度 ページの再生成を行うか
+   // 前のビルドで生成されたページはキャッシュされる
+   revalidate: 10, 
  }
}
```

## :file_folder: ディレクトリ構造とルーティング
### ディレクトリに関して
Next.jsでは、`pages`と`public`以外のディレクトリルールはほとんどございません。

```
🗂 ワークスペース
　　└ 🗂 pages            - ページComponentを管理するディレクトリ
　　　　　　- 🗂 api            - API Routes を管理するディレクトリ
　　└ 🗂 public           - 静的ファイルを管理するディレクトリ
 - 📄 next-env.d.ts    - 型定義ファイル
 - 📄 next.config.js   - 設定ファイル
```

`libs`やら`components`やらを自動に追加してokです。

### ルーティングに関して

ルーティングの方法としては、`Nested routes`と`Dynamic Routes`の2つがあります。

#### `Nested routes`
そのままの意味で、ディレクトリの階層がそのままURLになります。

```
pages/index.tsx → https://〇〇
pages/contact.tsx → https://〇〇/contact
pages/interview/takashi → https://〇〇/interview/takashi
```

#### `Dynamic Routes`
`Dynamic Routes`は、1ファイルが1URLを生成するのではなくて、
`/blogs/<パラメータ>`とういURLがあった時に`パラメータ`部分を変数として受け取れて
自動的にルーティングしてくれる仕組みのことを指します。

ファイル名の付け方にルールがあり、基本ブラケット`[パラメータ名]`で作成できます。

```
① : blogs/1、blogs/2
pages/blogs/[id].js

② : ① & blogs/category/1 (階層数が自由になる)
pages/blogs/[...paths].js

③ : ② & pages/blogs ( 二重角かっこ [[]] で親階層を含めることができる )
pages/blogs/[[...paths]].js
```


## :tada: Next.js 12 が公開！！

近日、Next.jsの大幅アップデートが発表されました！！
Next.js12はこれまでで最大のリリースみたいですね！

https://zenn.dev/web_tips/articles/81a6db12f7cb2f

個人的には`middleware`がどんなインフラでも運用できるのであれば、期待値がでかいです！！

まだ触れていないので、触ってみたら記事にしようと思います〜