GatsbyJSブログにPaginationを実装してみた

2021-01-11

はじめに

おはようございます!こんにちは!こんばんは!
麻雀と芝生大好きおじさんことのふのふ(@rpf_nob)です!!

記事数が増えてきたこともあって、そろそろページネーションがあったほうがいいかな思ったので実装してみました。

公式ページに追加方法も記載されていますが、今回はgatsby-awesome-paginationというパッケージで簡単にできたので、こちらで解説します!!

  • 前提
  • パッケージのインストール
  • templatesフォルダ配下にpages/index.jsを移動
  • gatsby-node.jsの編集
  • pages/index.jsの編集
  • components/pagenation.jsの作成
  • まとめ

前提

このブログはGatsbyJSのgatsby-starter-blogのテンプレートから作成しています。

パッケージのインストール

今回はgatsby-awesome-paginationを使って実装します。

$npm install --save gatsby-awesome-pagination

こちらのパッケージで簡単にページネーションを実装できます。

templatesフォルダ配下にpages/index.jsを移動

まず初めにpages/index.jsをtemplatesフォルダ配下に移動します。

gatsby-node.jsの編集

次にインストールしたgatsby-awesome-paginationからpaginateをインポートします。

gatsby-node.js
const { paginate } = require("gatsby-awesome-pagination");

そして以下のように、createPagesに追記します。

templateに先ほど移動したpages/index.jsの編集を指定します。

pathPrefixに設定する値で、1ページ目は ROOTURL/で2ページ目以降は ROOTURL/page/2になるように設定します。

gatsby-node.js
exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;
  const template = path.resolve(`src/templates/index.js`);
  const result = await graphql(
    `
      {
        posts: allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }, limit: 1000) {
          ・・・
      }
    `
  );
  if (result.errors) {
    throw result.errors;
  }
 
  const posts = result.data.posts.edges;

  paginate({    createPage,    items: posts,    itemsPerPage: 5,    component: template,    pathPrefix: ({ pageNumber }) => (pageNumber === 0 ? "/" : "/page"),  });

こちらでgatsby-node.jsの編集は完了です。

pages/index.jsの編集

次にpages/index.jsを編集します。

まず始めにpageQueryでskipとlimitを取得できるようにします。

src/templates/index.js
export const pageQuery = graphql`
  query($skip: Int!, $limit: Int!) {    site {
      ・・・
    }
    allMarkdownRemark(
      sort: { fields: [frontmatter___date], order: DESC }
      skip: $skip      limit: $limit    ) {
      edges {
        ・・・
      }
    }
  }
`;

次にテンプレートのコンポーネントにpageContextがわたってくるのでpropsとして受け取り、次で作成するPagenationコンポーネントをBioコンポーネントの上に設置して、同じようにpageContextをpropsで渡してあげます。

src/templates/index.js
const BlogIndex = ({ data, location, pageContext }) => {  const siteTitle = data.site.siteMetadata.title;
  const author = data.site.siteMetadata.author.name;
  const posts = data.allMarkdownRemark.edges;

  return (
    <div>
      <Layout location={location} title={siteTitle} author={author}>
        ・・・
        <Pagenation pageContext={pageContext} />        <Bio />
        <Adsense />
      </Layout>
    </div>
  );
};

components/pagenation.jsの作成

最後にPagenationコンポーネントを作成します。

今回はmaterial uiのページネーションコンポーネントを使います。


ソース全文

src/components/pagenation.js
import React from "react";
import { navigate } from "gatsby";
import { makeStyles } from "@material-ui/core/styles";
import { Pagination } from "@material-ui/lab";

const useStyles = makeStyles(theme => ({
  root: {
    display: `flex`,
    flexWrap: `wrap`,
    justifyContent: `center`,
    alignItems: "center",
  },
}));

const Pagenation = ({ pageContext }) => {
  const classes = useStyles();
  const { numberOfPages, humanPageNumber } = pageContext;

  const handleChange = (event, value) => {
    value === 1 ? navigate(`/`) : navigate(`/page/${value}`);
  };
  return (
    <div className={classes.root}>
      <Pagination
        size="small"
        defaultPage={humanPageNumber}
        count={numberOfPages}
        color="primary"
        onChange={handleChange}
      />
    </div>
  );
};
export default Pagenation;

pageContextからnumberOfPagesとhumanPageNumberを取り出します。

  • numberOfPagesは総ページ数
  • humanPageNumberは現在のページ番号

material uiのPaginationコンポーネントを設置して以下渡します。

  • defaultPageにhumanPageNumberを渡す
  • countにnumberOfPagesを渡す
  • onChangeにhandleChangeを渡す(後述)

defaultPageを設定してあげないと、ページ遷移時に1ページに目に見た目だけ戻ってしまいます。

handleChangeはページ番号クリック時の処理を記載します。

valueにページ番号が渡ってくるので、それに対応したページに遷移してあげます。
ページ遷移にはgatsbyからnavigateをインポートしてこちらを使います。react-routerのhistory.pushみたいなものです。

これで次のようにページネーションがいい感じに実装できました!!

img

まとめ

今回はgatsby-awesome-paginationというパッケージでページネーション実装をしたので方法を解説しました!!

ページネーションがあるとちゃんとしたブログっぽくなりますね。
もっと記事数を増やしてページネーションが意味あるものにしていきたいと思います!!
有用な記事数も増やせるようにしていきたいですね・・・

他にもGatsbyJSのブログカスタマイズをいろいろやっているので、以下もあわせてご覧いただければと思います。



最後まで見ていただきありがとうございます!!


Written by のふのふ

東京で働く名古屋生まれの麻雀と芝生と娘と妻を愛するアラフォーエンジニアです。 フロントエンドよりのweb開発技術(React,TypeScriptなど)を中心に扱っています。 web開発やデータサイエンス周りの技術に興味があります。 個人開発でwebアプリをリリースすることを目標にしています。

©2020 のふのふ All Rights Reserved.