LoginSignup
0
0

More than 1 year has passed since last update.

Next.js の SG, ISR (with Apollo) の仕組みを作りながら学んでみた(ユーザーの一覧ページのコンポーネント作成)2/5

Last updated at Posted at 2021-11-21

はじめに

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

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

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

今回は、ユーザーの一覧ページのコンポーネント作成の実装について書きます。

目次

SGという用語に関して

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

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

最終的なゴール

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

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

目的

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

必要なモジュールのimport

import { VFC } from 'react'
import Link from 'next/link' // 詳細ページへリンクするので
import { GetStaticProps } from 'next' // 関数getStaticPropsの型
import { initializeApollo } from '../lib/apolloClient' // Hasuraにデータ取得するためのGraphQlクライアントメソッド
import { GET_USERS } from '../queries/queries' // Hasuraにデータ取得するためのクエリ
import { GetUsersQuery, Users } from '../types/generated/graphql'  // クエリを書いたら自動生成される型情報
import { Layout } from '../components/Layout'

interface作成

前回実装した関数getStaticPropsからreturnされる users

ここね👇

return {
  props: { users: data.users },
  revalidate: 1,
}

このusersは今回実装するコンポーネントのpropsに渡ってきます。

そのpropsの型をinterfaceで定義します。

interface Props {
  users: ({
    __typename?: 'users'
  } & Pick<Users, 'id' | 'name'>)[]
}

配列で定義されています。その中身はオブジェクトになっていて、typesがusersidnameが定義されます。

Usersをホバーすると全体感把握できますが、その中から必要なものをPick UP してidnameって感じです。

スクリーンショット 2021-11-21 8.59.33.png

実際に以下の記事(Hasura)で作成してきたユーザーデータを

関数getStaticProps経由で取得した結果を

console.log(users)

これで見てみると

[
    {
        "__typename": "users",
        "id": "5f172cd2-221c-4ea5-8b83-6420b18860ab",
        "name": "lilly"
    },
    {
        "__typename": "users",
        "id": "0458dd7d-70a5-4087-88c7-d8c3ed51a505",
        "name": "bob"
    },
    {
        "__typename": "users",
        "id": "f6a27de5-2f26-4e14-8435-bc463aabe791",
        "name": "Paul"
    }
]

interface通りですね。

コンポーネント作成

const HasuraSG: VFC<Props> = ({ users }) => {
  console.log(users)
  return (
    <Layout title="Hasura SG">
      <p className="mb-3 font-bold">SG+ISR</p>
      {users?.map((user) => {
        return (
          <Link key={user.id} href={`/users/${user.id}`}>
            <a className="my-1 cursor-pointer" data-testid={`link-${user.id}`}>
              {user.name}
            </a>
          </Link>
        )
      })}
    </Layout>
  )
}
export default HasuraSG

usersが存在すれば、ユーザーの数分だけ詳細ページへのリンクを作成しています。

ブラウザ確認するとSGで取得されたページが表示されます。

ためしにブラウザのJSを無効化してもリロードしても表示されます。

なぜなら、前回説明したpre-rendering(意味を先に言うと、事前にHTMLを生成すること)が、適切に機能しているからです。

Reactだけで作った場合、こうはなりません。

作成したファイル

長いので折り畳みました。
import { VFC } from 'react'
import Link from 'next/link'
import { GetStaticProps } from 'next'
import { initializeApollo } from '../lib/apolloClient'
import { GET_USERS } from '../queries/queries'
import { GetUsersQuery, Users } from '../types/generated/graphql'
import { Layout } from '../components/Layout'

interface Props {
  users: ({
    __typename?: 'users'
  } & Pick<Users, 'id' | 'name'>)[]
}

const HasuraSG: VFC<Props> = ({ users }) => {
  console.log(users)
  return (
    <Layout title="Hasura SG">
      <p className="mb-3 font-bold">SG+ISR</p>
      {users?.map((user) => {
        return (
          <Link key={user.id} href={`/users/${user.id}`}>
            <a className="my-1 cursor-pointer" data-testid={`link-${user.id}`}>
              {user.name}
            </a>
          </Link>
        )
      })}
    </Layout>
  )
}
export default HasuraSG

export const getStaticProps: GetStaticProps = async () => {
  const apolloClient = initializeApollo()
  const { data } = await apolloClient.query<GetUsersQuery>({
    query: GET_USERS,
  })
  return {
    props: { users: data.users },
    revalidate: 1,
  }
}

まとめ

今回は、ユーザーの一覧ページのコンポーネント作成の実装について書きました。

次回

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

0
0
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
0