Table of Contents

tips_gatsby

[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以降が必要です。

shell
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) を利用して絞り込みを行います。

JSX
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 メソッドを使用してリンク付きのリストを作成します。

import React from "react";
import { Link, useStaticQuery, graphql } from "gatsby";
const Navigation = () => {
const data = useStaticQuery(graphql`
query NavQuery {
categories: allMarkdownRemark(limit: 2000) {
group(field: frontmatter___category) {
fieldValue
totalCount
}
}
}
`);
const categoryList = data.categories.group.map(cat => (
<li key={cat.fieldValue}>
<Link to={'/categories/' + cat.fieldValue}>
<FiFile />
{cat.fieldValue}
</Link>
</li>
));
return (
<nav>
<ul>
{categoryList}
</ul>
</nav>
);
};
export default Navigation;
view raw Navigation.js hosted with ❤ by GitHub

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

<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>

参照

© 2019 chocolat All Rights Reserved.