sena-v.com

sena-v.com
画像

画像

画像
scroll top

GatsbyにおけるGraphQLの役割について

GatsbyにおけるGraphQLの役割について

a


GatsbyにおけるGraphQLの挙動について、公式チュートリアル・参考サイトで得られる情報は
順番に学習することを想定しているため、ピンポイントでの理解が難しくなっている。

差別化のため、この記事では何をしたいときにどこを触るかという逆引き形式で
GatsbyにおけるGraphQLの使用方法をまとめる。

GraphQL挙動の前提

基本的には各コンポーネントを構成する.jsファイル内で定義をすることで、内部処理が行われ
Gatsbyの黒魔術で結果が返却される。

おおまかな流れとしては以下になる。

JSXを生成するコンポーネントを読み込む

queryをexportして読み込んだgraphQLモジュールに投げる

モジュール内部で処理し、結果をdataオブジェクトとしてグローバルに返却

返却されたdataオブジェクトを用いてJSXで表示させる。

用途に応じたGraphQL記法の違い

テンプレートを使用したページを生成する場合(各記事画面等)

  • gatsby-node.js内部にクエリを記述し、ビルド時に処理される
  • クエリにて取得した値について任意のラベル付けを行い、テンプレートに流し込んでページを生成する
  • 複数のページ生成を実施したい場合、各Objectのラベル付けが必要

2個のオブジェクトを生成するクエリを発行 data:{ posts:{ obj }, tags:{ obj } }

  const result = await graphql(`
    query {
      posts: allMarkdownRemark {              // ①各記事の表示に使用する情報
        edges {
          node {
            frontmatter {
              slug
              tags
            }
          }
        }
      }
      tags: allMarkdownRemark(limit: 1000) {  // ②タグ表示に使用する情報
        group(field: frontmatter___tags) {
          tag: fieldValue
          totalCount
        }
      }
    }
  `)



Topページ等の主ページコンポーネントで情報を取得する場合

  • 主コンポーネントでqueryを定義してexportする事により、graphQLモジュールが吸い上げて処理し
    dataオブジェクトを返却する
  • queryの定義自体は特に指定箇所は無いが、できるだけ視認性を良くするため間に挟まないようにする

1個のオブジェクトを生成するクエリを発行 data: allMarkdownRemark{ obj }

export const query = graphql`
  query {
    allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
      edges {
        node {
          frontmatter {
            title
            date(formatString: "YYYY年MM月DD日")
            tags
            slug
          }
          excerpt
        }
      }
    }
  }
`



コンポーネントに読み込んだ子の内側で情報を取得する場合

  • 子コンポーネント内でuseStaticQueryを使用する
  • exportしているメソッド内でJSXをreturnする形に変更し、return前にqueryを記述する

1個のオブジェクトを生成するクエリを発行 data: allMarkdownremark:{ obj }

  const data = useStaticQuery(
    graphql`
    query {
      allMarkdownRemark(limit: 1000) {
        group(field: frontmatter___tags) {
          tag: fieldValue
          totalCount
        }
      }
    }
  `
  )

  /* 以下、dataにて取得結果を使用できる */



未検証

親から子コンポーネントへ渡せなくはないと思うが…

子要素の中でgraphQLの結果を使用したい場合、子要素内でクエリ発行を行う方法(useStaticQuery)と
親コンポーネントで生成したqueryから取得したObjectを子要素に渡す方法が考えられる

SQLと同じ考え方をするのであれば、子要素内でクエリ発行する場合単純化でき保守性が上がるメリットがあり、
親コンポーネントから子要素へ渡す場合はクエリ発行回数が1回以上減らせるメリットがある。

Gatsbyレベルの動作であればpropsのバケツリレーをするよりクエリ発行してしまったほうが実装が楽なので
親でクエリを複雑にするよりは子コンポーネントを作ってしまったほうが楽じゃないかなと~思う。
(子要素が10-20個とかになるなら発行回数の差がエグいけど、そんなケースなさそうだし)

まとめ

dataは単数のコンポーネントで取得したい? → 複数 → gatsby-node.jsに記述
                ↓
               単数
                ↓
そのコンポーネントはメインのJSXを出力する? → NO → 親コンポーネントのグローバル変数にクエリを記述
                ↓
               Yes
                ↓
子コンポーネントのためuseStaticQueryを用いてメインメソッドのローカル変数にクエリを記述

Author: sena-v       © 2021, Built with Gatsby