はじめに
以下のゴールを達成するため、本日はついに、Next.jsとHasuraを連携してデータを画面に出すところまでやります。
特に今回は、Next.jsでApollo Clientを使ってSSR(SSG)する仕組みの部分を見て行くと思います。
Hasuraにあるデータやエンドポイントは既に用意してあります。
最終的なゴール
以下のような構成のアプリを作ることです。
目的
- 仕事で使っている技術のキャッチアップと復習
- 使う可能性がある技術の理解度向上
前回のおさらい
Next.jsとHasuraを連携してデータを画面に出すために、
apolloClientインスタンスを作成したり、初期化に関する処理を作成しました。
詳細👇
次に、pages配下にuseQueryを書きました。
詳細👇
pages配下のコンポーネント実装
前回はここまで書いたと思います。
import { VFC } from 'react'
import Link from 'next/link'
import { useQuery } from '@apollo/client'
import { GET_USERS } from '../queries/queries'
import { GetUsersQuery } from '../types/generated/graphql'
import { Layout } from '../components/Layout'
const FetchMain: VFC = () => {
const { data, error } = useQuery<GetUsersQuery>(GET_USERS)
return()
}
export default FetchMain
通信して、エラーだった場合、そうでない場合でコンポーネントを作成しましょう。
import { VFC } from 'react'
import Link from 'next/link'
import { useQuery } from '@apollo/client'
import { GET_USERS } from '../queries/queries'
import { GetUsersQuery } from '../types/generated/graphql'
import { Layout } from '../components/Layout'
const FetchMain: VFC = () => {
const { data, error } = useQuery<GetUsersQuery>(GET_USERS)
if (error)
return (
<Layout title="Hasura fetchPolicy">
<p>Error: {error.message}</p>
</Layout>
)
return (
<Layout title="Hasura fetchPolicy">
<p className="mb-6 font-bold">Hasura main page</p>
{data?.users.map((user) => {
return (
<p className="my-1" key={user.id}>
{user.name}
</p>
)
})}
<Link href="/hasura-sub">
<a className="mt-6">Next</a>
</Link>
</Layout>
)
}
export default FetchMain
通信ステータスごとに、returnされるコンポネントはどちらも<Layout/>
に囲みます。
{data?.users.map((user) => {
return (
<p className="my-1" key={user.id}>
{user.name}
</p>
)
})}
この解説を少しします。
data?.users
は、オプショナルチェーンが書かれています。
data
がnull | undefined
だと、data.users
これ、エラーになります
ですが、オプショナルチェーンで書くとそうならず、関数useQuery
の結果data
が存在しない場合は最終的に何も返らないコンポネントになります。
関数useQuery
の結果data
が存在する場合は配列の要素をそれぞれ、コンポネント(pタグ)作成しています。
実際にブラウザ(ローカル環境)を見ると
http://localhost:3000/hasura-main
HasuraのGraphQlサーバからUsersデータを取得できたことを確認できました。
コンソールでdataを確認するとこんな感じ
{
"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":"john"
}
]
}
GraphQlでは、キャッシュのデータが自動的に正規化され、"__typename":"users"
というKey & Valueが自動生成されます。
apolloクライアントが、保存されたキャッシュを追跡する場合、この場合は、id
と__typename
を組み合わせたものをKeyとして探索します。
今日のところは以上です。
次の記事では、Hasuraから取ったデータをキャッシュして、そのキャッシュデータを他のコンポーネントが再度が利用するための方法を書いていきます。
アウトプット100本ノック実施中