0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Next.js の SG, ISR (with Apollo) の仕組みを作りながら学んでみた(getStaticProps と getStaticPaths の理解と実装)1/5

Last updated at Posted at 2021-11-20

はじめに

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

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

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

今回は、getStaticProps と getStaticPaths の理解と必要な実装について書きます。

目次

SGという用語に関して

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

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

最終的なゴール

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

スクリーンショット 2021-10-18 17.27.41.png

目的

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

pre-renderingについて

(意味を先に言うと、事前にHTMLを生成することです。)

Next.jsにおいて、重要な概念にpre-renderingがあります。

Next.jsは、デフォルトで全てのページでpre-renderingしています。

ちなみに、React単体にはpre-renderingの機能はありません。

なので、通常のReactで構築されたページよりもSEO的なメリットもあるかもです。

hydration

pre-renderingされると、HTMLは必要最低限のJSコードとともに生成されます。

ブラウザによるロード時にこのJSが実行され、ページが完全にインタラクティブなものになります。

これをハイドレーション(hydration)と呼びます。

pre-renderingには二種類ある

pre-renderingには二種類あります。

  • 外部データを必要としないpre-rendering
  • 外部データを必要とするpre-rendering
    • 外部API(本記事ならHasuraなど)から取得してきたデータを一覧表示するページを作成したいとき
      • そんなときに使用するのがgetStaticProps

getStaticPropsとgetStaticPathsの要点

  • getStaticProps
    • ビルド時に静的なファイルを生成し、ページコンポーネントで使用する値を用意する
    • Next.jsでpre-renderingを行う際に、外部データが必要な時に使用する関数
      • pre-rendering : webページにアクセスする前にページを表示するのに必要なHTMLを構成しておく」という意味です
  • getStaticPaths
    • ビルド時にレンダリングする必要のあるパスのリストを生成する

これらの関数はクライアント側での実行でなく、必ずサーバーサイドで実行されます。

getStaticProps

getStaticPropsgetStaticPathsはSG用のAPIで、静的なデータを事前(ビルド時)に生成してくれます。

クライアント側で実行されず、サーバーサイドで実行されますが、アクセスの度にSSRはしません。

ビルド時にデータを取得し静的なファイルを事前に生成します。

なので、再ビルドしない限りいつアクセスしても同じ結果です。

getStaticPaths

のちのち説明するので、getStaticPathsの概要も把握しておきます。

getStaticPathsDynamic Routes利用時にも静的なファイルを生成するためのAPIです。

こちらも、getStaticPropsと同様に、再ビルドしない限り、いつアクセスしても結果は同じです。

Dynamic Routesとは

Next.jsでは、pages/配下でファイル名にブラケット([])を使用することで自動的にダイナミックルーティングされる仕組みのことです。

ダイナミックルート用のファイルでは、getStaticPathsgetStaticPropsの関数が必要です。

このシリーズ内の今後の記事で実装していきます。

実装

本記事で必要な部分だけ実装しました。

// GetStaticProps 用の型
import { GetStaticProps } from 'next'
import { initializeApollo } from '../lib/apolloClient'
// GetStaticProps で、ユーザーのリストを取得するのでqueriesからimport
import { GET_USERS } from '../queries/queries'
// GET_USERSの型
import { GetUsersQuery } from '../types/generated/graphql'

// ビルド時にサーバーサイドで実行される
export const getStaticProps: GetStaticProps = async () => {
  // サーバーサイドでinitializeApolloを実行し、apolloClientを生成
  const apolloClient = initializeApollo()
  // 生成したapolloClientで、クエリ(GET_USERS)をHasuraに投げる
  // await で同期化して、{ data } で受け取っている
  const { data } = await apolloClient.query<GetUsersQuery>({
    query: GET_USERS,
  })
  // usersという名前にして、user情報を返している
  // 
  return {
    props: { users: data.users },
    revalidate: 1,
  }
}

revalidate

関数getStaticPropsからreturnするオブジェクトの中で、revalidateというキー名に対して数値を指定します。

この単位は秒数です。なので、ここでは 1 ですから 1 秒という時間を指定しています。

revalidateを指定すると、自動的にISRが有効化されます。

revalidateをたとえば 1秒に指定すると、getStaticPropsを使ってSGが行われる各ページについて、1秒間はこれまでと同様に静的な HTML(のキャッシュ)をサーブします。

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

これにより、時間の経過に応じて内容が変化する部分でも、アプリ全体を再ビルドすることなくその変化を反映させることができます。

今は秒数を 1秒として説明しましたが、データの性質に応じてこの秒数を調整できます。

また、revalidateで指定した時間の経過後にリクエストが行われ、ページを再生成している間は、再生成する前の(つまり、生成済みの)HTML(のキャッシュ)を返すので、ページを再生成するタイミングで応答が遅くなるというようなことはありません。

またデータの再取得に失敗するなどしてページの再生成ができなかった場合は、過去にサーブしていたキャッシュがその後もサーブされます。

まとめ

今回は、getStaticProps と getStaticPaths の理解と必要な実装について書きました。

参考

次回

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

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?