Next.js の SG, ISR (with Apollo) の仕組みを作りながら学んでみた（作ったものの検証しつつSGとISRの仕組みを学ぶ）5/5

## はじめに

Next.js の SG + ISR (with Apollo) の仕組みを作りながら学んでみたシリーズ

このシリーズでは、Hasuraで用意した仮想のユーザーデータを外部APIとして取得しながら、

ユーザーの一覧ページと詳細ページを作りながら、SGと ISRを学ぶ記事です。

https://qiita.com/ryosuketter/items/ab7d4c8bfb19185f7b1e

今回は、作ったものをブラウザで見ながらSGとISRの仕組みをざっくり書きます。

## 目次

- 実装
    - 一覧ページ
        - [getStaticProps](https://qiita.com/ryosuketter/items/442db08856093e6cfeea)
        - [必要なモジュールのimport](https://qiita.com/ryosuketter/items/8c4820c06a441c717180)
        - [interface作成](https://qiita.com/ryosuketter/items/8c4820c06a441c717180)
        - [コンポーネント作成](https://qiita.com/ryosuketter/items/8c4820c06a441c717180)
    - 詳細ページ
        - [getStaticProps と getStaticPaths](https://qiita.com/ryosuketter/items/799d3330ab7cda37145c)
        - [必要なモジュールのimport](https://qiita.com/ryosuketter/items/cb2507559c6c71bf9f17)
        - [interface作成](https://qiita.com/ryosuketter/items/cb2507559c6c71bf9f17)
        - [コンポーネント作成](https://qiita.com/ryosuketter/items/cb2507559c6c71bf9f17)
- 検証
    - [作ったものをブラウザで見ながらSGとISRの仕組みをざっくり理解する](https://qiita.com/ryosuketter/items/af45c292249ea7a88d9d) 👈 今回はコレ

## SGという用語に関して

SSGと言ったり、SGと言ったりするかもしれませんが、SSGはかつての呼び方なのでSG（Static Generate）に統一して書こうと思います。

仕組みは同じものだと思ってください。

## 最終的なゴール

以下のような構成のアプリを作ることです。

![スクリーンショット 2021-10-18 17.27.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/e8a9a2e1-2723-4fec-77ef-be3b9eefdd81.png)

### 目的

- 仕事で使っている技術のキャッチアップと復習
- 使う可能性がある技術の理解度向上

## 検証してみる

:::note warn
新たにSGするファイルを作る際やgetStaticPropsとgetStaticPathsを作った結果をデバッグしたい時は
yarn build してからブラウザで確認してください
:::

```
$ yarn build
$ yarn start
```

一覧ページと詳細ページを行き来できることを確認できます。

![e972283708de7d604b85fadb4fe99490.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/00da50cc-f001-54cc-21b6-e460d3ad2717.gif)

ページ遷移のたびにNetworkに何も追加されません。

これは事前ビルド`pre-rendering`が完了しているからでしょう。

![a9159a7cf3b0000e31788b252e4f7717.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/0e520679-fe49-e17f-a866-ffffbaa73ad7.gif)

## 管理画面（Hasura）からユーザーを追加してブラウザ検証してみる

ISRの挙動を確認するため、サーバーからデータを追加して、ブラウザで確認すると

最初は古いHTMLが出ます。次、リロードすると、`revalidate`の設定時間にもよりますが、サーバーから追加したデータが表示されると期待しています。

管理画面（Hasura）からユーザーを追加します。

![Insert_-_users_-_Data___Hasura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/12d834bb-1de6-57aa-2cc3-caf883d03c80.png)

追加されていますね。

![Browse_-_users_-_Data___Hasura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/81ca9712-dc6e-8347-6554-dc1d56288961.png)

1回目のアクセスでは、さっき追加した`John`は確認できず。

![スクリーンショット 2021-11-21 22.59.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/5f2c69b7-6f3b-7326-ae20-3295d9285afd.png)

ただし、裏側では`John`を表示するためのページの再生成を行なっています。

関数 `getStaticProps`から`return`するオブジェクトに`revalidate`というキーに対して今回は1（秒）を指定しました。

ISRは「一定時間ごとにバックグラウンドでデータの再取得およびページの再レンダリングを行」だと思うので`revalidate`プロパティで指定される秒数は、まさにその「一定時間」に相当するものでしょう。

`revalidate`を1秒に指定したので、`getStaticProps`を使って`SG`が行われる各ページについて、少なくとも1秒間はこれまでの説明と同様に静的な HTML（のキャッシュ）を返します。

しかし、1秒経過した後に初めてユーザーからリクエストがあったタイミングで、そのリクエストに対してはすでに構築済みのHTML（のキャッシュ）を返しつつ、バックグラウンドでHasuraからデータの再取得、および再レンダリングを行いページを再生成し、次のリクエストに対しては再生成したページのキャッシュを返しています。

2回目のリロードで`John`が表示されましたね。

![0865672a40f3b3187f094d3f3cf4824e.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/a8634c2a-66b5-837a-742a-33941d5087ba.gif)

図で表すとこんな感じでしょうか。

![スクリーンショット 2021-11-22 1.04.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/f623dc46-4cd7-7c2a-1fad-608bee488870.png)

SGとISRに関しては、以下の説明が居酒屋に例えられて分かりやすかったです。

https://speakerdeck.com/aiji42/70mo-tong-rifalseurlwochi-tuwebsabisuwo-next-dot-jsniripureisusitegao-su-hua-sitahua?slide=18

## まとめ

今回は、作ったものをブラウザで見ながらSGとISRの仕組みをざっくり書きました。

このシリーズはコレで以上です。

## アウトプット100本ノック実施中

https://qiita.com/ryosuketter/items/713474dbd009870e4103