Chapter 18

記事データの取得

Contentfulとの連携設定は終わったので、実際にContentfulからデータを取得してみましょう。

クエリの確認

http://localhost:8000/__graphql にアクセスしてみましょう。
画面左側のExplorerにallContentfulPostというクエリが追加されていると思います。
このクエリによって、Contentfulに登録したすべての記事データ(公開しているものに限る)を取得することができます。
contentful-query.png

画面中央のエディタに以下のようにクエリを書いて実行してみましょう。登録したデータを取得できるはずです。

query MyQuery {
  allContentfulPost {
    edges {
      node {
        title
        image {
          title
          file {
            url
          }
        }
        description {
          description
        }
        slug
        updatedAt(locale: "ja-JP", formatString: "YYYY年MM月DD日")
      }
    }
  }
}

edgesとnode

クエリ内にedgesnodeというデータとして定義していないワードが出てきました。
これらはGraphQLでリスト形式のデータをページネーションで扱うためのもので、ConnectionsというFacebookが定めた規約に記載されています。
Connectionsの詳しい説明については、こちらのページで紹介されています。

allContentfulPostでは、一部のデータだけページングで取得することもできます。
そのため、Connectionsの規約に従ってedgesnodeがクエリ内で用いられています。

データ更新時の注意点

Contentfulのデータを更新した場合には、gatsby developで開発サーバーを立ち上げ直す必要があります。
gatsby developの際にGatsbyがContentfulからデータを一括で取得しています。それ以降はデータは更新されないためです。
これはGatsbyのパフォーマンスに大きく寄与しています。最初に一括でデータを取得することによって、ページ描画時にContentfulのAPIからデータを取得しなくても良いためです。

コンポーネントへのデータ連携

ページからGraphQLを使うには、src/pages/index.jsに以下のように書きます。
18 〜 39行目のようにgraphqlで囲われたクエリをexportすることで、Gatsbyがその結果をPageのコンポーネント(ここではHome)にdataとして渡してくれます。
そのdataをPostLinkコンポーネントへ渡します。

// src/pages/index.js
import React from "react"
import Layout from "../components/layout"
import Hero from "../components/hero"
import PostLink from "../components/post-link"
import { graphql } from "gatsby"

export default function Home({ data }) {
  return (
    <Layout>
      <Hero />
      {data.allContentfulPost.edges.map(edge =>
        <PostLink key={edge.node.slug} post={edge.node} />
      )}
    </Layout>
  )
}

export const query = graphql`
    query allContentfulPost {
      allContentfulPost {
        edges {
          node {
            title
            image {
              title
              file {
                url
              }
            }
            description {
              description
            }
            slug
            updatedAt(locale: "ja-JP", formatString: "YYYY年MM月DD日")
          }
        }
      }
    }
`

渡ってくるデータを受け取れるように以下のようにコードを編集します。

// src/components/post-link.js
import React from "react"
import "../styles/post-link.css"

export default function PostLink({ post }) {
    const { title, updatedAt, image } = post;
    const description = post.description.description;

    return (
        <div className="post-link">
            <div>
                <img src={image.file.url} className="post-link-image" alt="post-cover"></img>
            </div>
            <div className="post-link-text">
                <h2>{title}</h2>
                <p className="post-link-body">{description}</p>
                <p className="post-link-date">{updatedAt}</p>
            </div>
        </div>
    )
}

表示結果

Contentfulのデータを連携し、作成した記事の一覧を表示することができました。
次は、記事詳細ページを作成していきましょう。
result.png