Skip to content

[GatsbyJS] React Hookを使用してGraphQLでナビゲーションにカテゴリーリストを表示する

React Hookを使用してGraphQLをクエリする新機能 useStaticQueryGatsby v2.1.0から導入されました。

ヘッダーやフッターコンポーネント内でGraphQLから取得したデータを使用するためには、Layoutやページコンポーネントから props を通してデータを渡す必要がありましたが、Gatsby v2から導入された新しいAPI StaticQuery を使用することで、ヘッダーやフッターコンポーネント内で直接GraphQLのデータを取得できるようになりました。

useStaticQuery はReact Hooksを使用するバージョンです。

実現したいこと

  • useStaticQuery を使用して任意のコンポーネントでGraphQLのデータを取得する
  • useStaticQuery で取得したデータでナビゲーションにカテゴリーリストを表示する

事前準備

動作にはReactとReactDOM 16.8.0以降が必要です。

npm install react@^16.8.0 react-dom@^16.8.0

基本的な使い方

使用したいコンポーネントで useStaticQuerygraohql をgatsbyからインポートします。

/** header.js */

import React from "react";
import { useStaticQuery, graphql } from "gatsby";

useStaticQuery でGraphQLのデータを取得するクエリを記述し、任意の名前をつけた変数として定義します。

/** header.js */

const data = useStaticQuery(graphql`
  query HeaderQuery {
    site {
      siteMetadata {
        siteUrl
      }
    }
  }
`);

console.log(data); // https://xxxxx.com

JSXで a タグのhrefにdata を指定したりなど、GraphQLをデータを任意のコンポーネント内で使用できるようになりました。

ナビゲーションにカテゴリーリストを表示する

サイトのカテゴリーを取得するには、GraphQLの group(field: xxxxx) を利用して絞り込みを行います。

const data = useStaticQuery(graphql`
  query CategoryQuery {
    allMarkdownRemark {
      group(field: frontmatter___category) {
        fieldValue
      }
    }
  }
`);

field に絞り込みの対象となるキーを指定します。サイト内の全カテゴリーを取得したいので frontmatter___category としています。Markdownファイルの先頭の --- で囲まれたエリアにcategoryが指定されている必要があります。

fieldValue はMarkdownファイルの category: "blog""blog" にあたります。

取得されるデータの一例です。当サイトでは下記のデータが取得できます。

{
  "data": {
    "allMarkdownRemark": {
      "group": [
        {
          "fieldValue": "blog"
        },
        {
          "fieldValue": "css"
        },
        {
          "fieldValue": "gatsby"
        },
        {
          "fieldValue": "javascript"
        },
        {
          "fieldValue": "react"
        }
      ]
    }
  }
}

カテゴリーリストが取得できたら、ナビゲーションコンポーネント内で、 map メソッドを使用してリンク付きのリストを作成します。

gist:chocolat5/f9235751628d1f8e341b4e71e7e0844f#Navigation.js

カテゴリーのリンクリストが表示されました。🎉

<ul>
  <li><a href="/categories/css">css</a></li>
  <li><a href="/categories/gatsby">gatsby</a></li>
  <li><a href="/categories/javascript">javascript</a></li>
  <li><a href="/categories/react">react</a></li>
</ul>

参照