[第4章：Gatsbyにおけるデータの扱い方 編] Gatsby公式ドキュメントを翻訳してみた。

# はじめに
このシリーズでは、英語ソースばかりで「Gatsby使ってみたいけど、よくわからない...」という方々のために、公式Docを翻訳（ところどころざっくり要約）していきます。

実際の公式ドキュメントは[こちら](https://www.gatsbyjs.org/tutorial/)

（この章では、GraphQLの概要を理解して実際にサイト内の情報を取得・表示させることがゴールです）

〜〜 以下、翻訳となります 〜〜

## 4. Gatsbyにおけるデータの扱い方
この章では、WordpressやMarkdownファイル、その他CMSなど様々なソースからデータを引っ張ってくることができるGatsbyサイトのデータ構造について学んでいきましょう。

> Gatsbyのデータ構造は、GraphQLによって成り立っています。詳しく知りたい方は、[こちら](https://www.howtographql.com/)（英語）

基本的なことですが、Webサイトは次の4つから成り立っていますよね。
 - HTML
 - CSS
 - JavaScript
 - データ
 
それではまず、そのデータについて学びましょう。

### データとは？
コンピュータサイエンスっぽく説明すると、「データとは、文字列（`"string"`）や整数（`42`）、オブジェクト（`{ pizza: true}`）といったような型をもったものの総称」です。

しかし、Gatsbyの学習においては、「Reactコンポーネントの外側にあるもの全て」と考えてもらった方がわかりやすいと思います。

この章に進むまで、あなたはコンポーネントの中に直接テキストや画像を書き込んでいました。しかし、自分が作成したコンポーネントの外にある情報やイメージをサイトに表示させたいこともあるでしょう。

例えば、もしWordpressとGatsbyを使用してサイトを作成しているのであれば、投稿した写真やテキストなどのデータを自分の作成したコンポーネントの中に引っ張ってきて表示させることが可能です。

これから学ぶGraphQLを使いこなせば、どんなソースからでも直接コンポーネントにデータを渡して表示できるようになります。

### GraphQLがどのようにしてコンポーネントにデータを渡しているのか
データを取得してReactコンポーネントに渡す方法はたくさんあります。その中でも最も有名で人気なのが、このGraphQLです。

> GraphQLは、Facebookによって開発されたクエリ（query）言語です。クエリとは、クライアントとサーバー間の通信を行うときに利用されるもので、データベースに直接干渉するために使われます。

Gatsbyは、そのコンポーネントが必要としているデータを宣言するためにこのGraphQLというクエリを使います。

> GraphQLは大規模で複雑なサイトにおいて大きな力を発揮します。あなたの作成するサイトが小規模でデータの受け渡しも少ない場合は`createPages`のAPIなど、他の方法を使うことも検討した方がいいかもしれません。GraphQLを使用せずにGatsbyを使用したい場合は、[こちら](https://www.gatsbyjs.org/docs/using-gatsby-without-graphql/)（英語）をご覧ください。

### サイトを作成してGraphQLを使ってみよう
これから、パンダがたくさんの食べ物を食べている写真や動画を載せる「Pandas Eating Lots」というマークダウン式のブログサイトを作ります。これを通して。GraphQLの技術やGatsbyにおけるマークダウン形式ファイルの使いやすさを実感できることでしょう。

1 . まず、新しくターミナルのタブを開いて次のコマンドを実行します。

```shell
gatsby new tutorial-part-four https://github.com/gatsbyjs/gatsby-starter-hello-world
cd tutorial-part-four
```

2 . 次に、作業中のディレクトリに必要なnpmパッケージをインストールしましょう。Typographyの`"Kirkham"`というテーマとCSS-in-JSライブラリの`"Emotion"`を使います。

```shell
npm install --save gatsby-plugin-typography typography react-typography typography-theme-kirkham gatsby-plugin-emotion @emotion/core
```

[第3章](https://qiita.com/wlcmty/items/8302dcdc61debbd4132e)で作成したようなサイトを作ってみましょう。

src/components/layout.js

```jsx
import React from "react"
import { css } from "@emotion/core"
import { Link } from "gatsby"

import { rhythm } from "../utils/typography"

export default ({ children }) => (
  <div
    css={css`
      margin: 0 auto;
      max-width: 700px;
      padding: ${rhythm(2)};
      padding-top: ${rhythm(1.5)};
    `}
  >
    <Link to={`/`}>
      <h3
        css={css`
          margin-bottom: ${rhythm(2)};
          display: inline-block;
          font-style: normal;
        `}
      >
        Pandas Eating Lots
      </h3>
    </Link>
    <Link
      to={`/about/`}
      css={css`
        float: right;
      `}
    >
      About
    </Link>
    {children}
  </div>
)
```

src/pages/index.js

```jsx
import React from "react"
import Layout from "../components/layout"

export default () => (
  <Layout>
    <h1>Amazing Pandas Eating Things</h1>
    <div>
      <img
        src="https://2.bp.blogspot.com/-BMP2l6Hwvp4/TiAxeGx4CTI/AAAAAAAAD_M/XlC_mY3SoEw/s1600/panda-group-eating-bamboo.jpg"
        alt="Group of pandas eating bamboo"
      />
    </div>
  </Layout>
)
```

src/pages/about.js

```jsx
import React from "react"
import Layout from "../components/layout"

export default () => (
  <Layout>
    <h1>About Pandas Eating Lots</h1>
    <p>
      We're the only site running on your computer dedicated to showing the best
      photos and videos of pandas eating lots of food.
    </p>
  </Layout>
)
```

src/utils/typography.js

```js
import Typography from "typography"
import kirkhamTheme from "typography-theme-kirkham"

const typography = new Typography(kirkhamTheme)

export default typography
export const rhythm = typography.rhythm
```

下記の`gatsby-config.js`は、必ず最上層のディレクトリに設置しましょう。

gatsby-config.js

```js
module.exports = {
  plugins: [
    `gatsby-plugin-emotion`,
    {
      resolve: `gatsby-plugin-typography`,
      options: {
        pathToConfigModule: `src/utils/typography`,
      },
    },
  ],
}
```

上記全てのファイルを追加して、`gatsby develop`を実行しましょう。このようになっていればOKです。

![start.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482472/27c84eda-305d-5cc7-a714-0d99043c6bc9.png)

lauoutコンポーネントと2つのpageコンポーネントをもつサイトが完成しました。それでは、クエリを行なっていきましょう。

### GraphQLを使ってみよう
サイトを作成する時、サイトのタイトルなどのように複数ページで繰り返し使いまわしたいデータ（情報やイメージ）が少なからず出てきますよね。例えば、先ほど作成した`/about`ページの中では、layoutコンポーネントのヘッダーの中にあるサイトタイトル（`Pandas Eating Lots`）が`about.js`の中の`<h1/>`の中でも使われています。

しかし、もし将来あなたがサイトタイトルを変更したいと思ったらどうでしょうか？作ったのが昔であまり覚えていないあなたは、全てのコンポーネントを確認してサイトタイトルを表示している部分を見つけて直したいですか？

そうではなく、そういったデータの保存先を１つだけ用意しておいて必要な時に他のファイルからそのデータを呼び出してコンポーネントの中で表示する形にすれば、探す手間も省けますし、エラーも起きにくくて管理もしやすいです。

Gatsbyサイトでは、タイトルのような一般的なデータは全て`gatsby-config.js`の中の`siteMetadata`に保存します。あなたのサイトのタイトルを実際に入れて使ってみましょう。

gatsby-config.js

```js
module.exports = {
  siteMetadata: {
    title: `Title from siteMetadata`,
  },
  plugins: [
    `gatsby-plugin-emotion`,
    {
      resolve: `gatsby-plugin-typography`,
      options: {
        pathToConfigModule: `src/utils/typography`,
      },
    },
  ],
}
```

### クエリを実行してみよう
それでは、`about.js`を下記のように編集して、`localhost:8000/about`にアクセスしてみましょう。

src/pages/about.js

```jsx
import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"

export default ({ data }) => (
  <Layout>
    <h1>About {data.site.siteMetadata.title}</h1>
    <p>
      We're the only site running on your computer dedicated to showing the best
      photos and videos of pandas eating lots of food.
    </p>
  </Layout>
)

export const query = graphql`
  query {
    site {
      siteMetadata {
        title
      }
    }
  }
`
```

次のように、タイトルがちゃんと表示されましたか？

![site-metadata-title.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482472/44bc486d-ceb8-7f57-1956-32f97988916a.png)

今回行なったクエリは、以下のGraphQLコードです。

```graphql
{
  site {
    siteMetadata {
      title
    }
  }
}
```

これはpageクエリと呼ばれるもので、基本的にpageコンポーネントの最後の方に書かれます。実は、このpageクエリはpageコンポーネントでしか実行することができません。

### StaticQueryを使ってみよう
`StaticQuery`はGatsbyのv2から導入された新しいAPIで、pageコンポーネント以外でも実行することができます。`useStaticQuery`というものを実際にimportして使ってみましょう。

`src/components/layout.js`を以下のように編集してみましょう。

src/components/layout.js

```jsx
import React from "react"
import { css } from "@emotion/core"
import { useStaticQuery, Link, graphql } from "gatsby"

import { rhythm } from "../utils/typography"
export default ({ children }) => {
  const data = useStaticQuery(
    graphql`
      query {
        site {
          siteMetadata {
            title
          }
        }
      }
    `
  )
  return (
    <div
      css={css`
        margin: 0 auto;
        max-width: 700px;
        padding: ${rhythm(2)};
        padding-top: ${rhythm(1.5)};
      `}
    >
      <Link to={`/`}>
        <h3
          css={css`
            margin-bottom: ${rhythm(2)};
            display: inline-block;
            font-style: normal;
          `}
        >
          {data.site.siteMetadata.title}
        </h3>
      </Link>
      <Link
        to={`/about/`}
        css={css`
          float: right;
        `}
      >
        About
      </Link>
      {children}
    </div>
  )
}
```

下記のように、layoutコンポーネントにもGraphQLで取得したタイトルが表示されましたか？

![site-metadata-two-titles.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482472/49d0213f-6f66-4180-fbd2-6f63cf3a9ab7.png)

とりあえず、今回はpageコンポーネントにしか使えないクエリとそれ以外にも使えるクエリがあるということだけ覚えておいてください。5〜7章でもデータについて学びますし、まだGraphQLの学習は始まったばかりです。

最後に、サイトのタイトルを元の`“Pandas Eating Lots”`に戻しておきましょう。`gatsby-config.js`の中の`title`を編集するだけです。

![pandas-eating-lots-titles.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482472/09445e94-51e5-6b7a-1466-05b1a16e9056.png)

お疲れさまでした！

参考文献：[Gatsby公式ドキュメント](https://www.gatsbyjs.org/tutorial/)

次の章のテーマは、
「プラグインを活用してGraphQLを使ってみよう」です。

お楽しみに！！

[[第0章：環境構築編] Gatsby公式ドキュメントを翻訳してみた。](https://qiita.com/wlcmty/items/67b6f51ddc646484d7bc)

[[第1章：Gatsbyサイトの理解 編] Gatsby公式ドキュメントを翻訳してみた。](https://qiita.com/wlcmty/items/dcfcdf36ed660fd94ad7)

[[第2章：Gatsbyにおけるスタイリング 編] Gatsby公式ドキュメントを翻訳してみた。](https://qiita.com/wlcmty/items/1ecf954b60a016d249a4)

[[第3章：Layoutコンポーネントを使ってみよう 編] Gatsby公式ドキュメントを翻訳してみた。](https://qiita.com/wlcmty/items/8302dcdc61debbd4132e)