LoginSignup
1
3

More than 3 years have passed since last update.

ことばを学ぶ LEARN GATSBY 週間 #5日目

Posted at

こんばんは!

今回はページネーション機能を使ってみたいと思います.
ページネーション機能を利用するためのプラグインは何個かあるのですが、そのなかで一番便利な (悪く言うとプラグイン任せな) awesome-pagination を使います.
まずはプラグインをインストールします.

npm i gatsby-awesome-pagination

gatsby-node.js に以下を追加します.

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

const bloglistTemplate = path.resolve('./src/templates/blog-list-template.js')
    paginate({
        createPage, 
        items: res.data.allMarkdownRemark.edges, 
        itemsPerPage: 3, 
        pathPrefix: '/bloglist', 
        component: bloglistTemplate,
      })

さらに、bloglist.js の名前を blog-list-template.js とし、templates フォルダに入れます.
そして、blog-list-template.js を以下のように編集します.

blog-list-template.js
import React from 'react'
import { Link , graphql  } from 'gatsby'
import Layout from '../Layouts/common'

export const data = graphql`
query ($skip: Int!, $limit: Int!) {
    allMarkdownRemark (
        skip: $skip ,
        limit: $limit 
    ){

        edges {
            node {
                frontmatter {
                    title
                    date (formatString: "MMMM DD, YYYY")
                }
                excerpt
                fields{
                    slug
                }
            }
        }
    }
}
`
const BlogList = (props) => {

    return (
        <Layout>
            <h1>This is BlogList  </h1>
            <ol>
             {props.data.allMarkdownRemark.edges.map( ({node}) => {
                return (
                    <li key={node.fields.slug}>
                        <Link to={`/bloglist/${node.fields.slug}`} >
                            <h2>{node.frontmatter.title}</h2>
                            <p>{node.frontmatter.date}</p>
                        </Link>
                    </li>
                )
             })}
            </ol>
        </Layout>
    )
}

export default BlogList

開発用サーバーを起動して、Bloglist ページを見てみると、記事の数が3つになっています. これは、gatsby-node.js にて、itemsPerPage3 に設定したからです. http://localhost:8000/bloglist/2 にアクセスしてみると、続きの3つの記事が現れます.
このように、ページネーション機能を使うと、記事数が多くなった時に見やすく、記事数が少ない場合でも多く見せることができます.

ここでいったん、上のコードの意味を簡単に考えてみましょう. 
ページネーションを行うには 4つの情報 が必要です.
それは、すべての記事情報 ( items )、1ページに何個の記事を載せるか ( itemsPerPage )、各ページにつけたいパス ( pathPrefix )、利用するテンプレート ( component ) です.

これらの情報に加え、上の $skip , $limit を利用して、ページネーションしています. この二つは変数で必ず正の整数が与えられます.
例えば今6つ記事があり、itemsPerPage3 に指定したとき、$limit3 が与えられます. これは、1ページの記事の個数を 3 に限定 ( limit ) しているわけです.
http://localhost:8000/bloglist/2 に移動したとき、$limit に加え、$skip には 3 が与えられます. なぜなら、6 つの記事のうち最初の 3 つを飛ばしているから ( skip ) です.

つまり、ひとつのテンプレートを 使いまわして、情報だけを変えているから、あたかも、ページが切り替わっているように見えるというわけです.

さて、http://localhost:8000/bloglist/2 に行くためのリンクを作ってみましょう.
そのまま、blog-list-template.js にページリンクを書くと長くなるので、コンポーネントとして書いてみます.
src/componentspageCon.js を作成し、以下のように書きます.

pageCon.js
import React from 'react'
import { Link } from 'gatsby'

const Page = ( {context} ) => {
    const { previousPagePath , nextPagePath ,humanPageNumber , numberOfPages} = context
    return (

        <div className="container">
        <nav className="pagination" >
          <ul>
            {previousPagePath && (
              <p>
                <Link to={previousPagePath}  className="newer-posts">
                  Prev
                </Link>
              </p>
            )}
            <p>
              <span className="page-number">
                Page {humanPageNumber} of {numberOfPages}
              </span>
            </p>
            {nextPagePath && (
              <p>
                <Link to={nextPagePath} className="older-posts">
                  Next 
                </Link>
              </p>
            )}
          </ul>
        </nav>

      </div>
    )
}

export default Page

context とは pagination によって渡されるオブジェクトで、自動的に以下の値を受け渡します.

  • pageNumber - ページ番号 ( 0 から始まります )
  • humanPageNumber - ページ番号 ( 1 から始まります )
  • skip -  さきほど $skip が使えたのは context で自動的に受け渡されているからです
  • limit - $skipと同様
  • numberOfPages - トータルのページ数
  • previousPagePath - 前のページへのパスを表します
  • nextPagePath - 次のページへのパスを表します
{previousPagePath && (   ...

この && はもし、previousPagePath がなければ ( = undefined )、&& 以下は表示されないということです.

blog-list-template.js に以下を追加します.

blog-list-template.js
import Page from '../components/pageCon'

 <Layout>
 ... (省略)
 <Page context = {props.pageContext} />
</Layout>

これで、next previous を押してページ移動することができます !

次回は、 CSS で少し形を整えた後、ページネーションを各記事間に設置、タグを実装してみたいと思います.

ここまで読んでくださって、ありがとうございました.

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3