0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Posted at

今回は、各記事間のページネーションを実装したいと思います.

gatsby-node.js はこんな感じになっていると思います.

gatsby-node.js
const path = require('path')

module.exports.onCreateNode = ({ node , actions }) => {
    const { createNodeField } = actions
    if (node.internal.type === 'MarkdownRemark') {
        const slug = path.basename(node.fileAbsolutePath , '.md' )

        createNodeField({
            node,
            name: 'slug',
            value: slug
        })

    }

}
module.exports.createPages = async ({ graphql , actions }) => {
    const { createPage } = actions
    const blogTemplate = path.resolve('./src/templates/blog-template.js')

    const res = await graphql(`
        query {
            allMarkdownRemark {
                edges {
                    node {
                        fields {
                            slug
                        }
                    }
                }
            }
        }
    `)

    res.data.allMarkdownRemark.edges.forEach( ({ node }) => {
        createPage({
            component: blogTemplate ,
            path: `/bloglist/${node.fields.slug}` ,
            context: {
                slug: node.fields.slug
            }
        })
    })

    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,
      })
}

ここでページや、スラグなどの情報を作るのでした.
注目してほしいのは以下の部分.

 query {
            allMarkdownRemark {
                edges {
                    node {
                        fields {
                            slug
                        }
                    }
                }
            }
        }

これはすべての記事情報を表すクエリです. 記事間を移動するページネーションを実装するには、前後の記事リンクが分からないと移動できませんよね. allMarkdownRemark 内にて前後の記事リンク (パス) を取得できるクエリがあります. それが next previous です. 以下のように書き直します.

 query {
        allMarkdownRemark {
          edges {
            previous{
              frontmatter {
                    title
              }
              fields {
                slug
              }
            }
            next {
              frontmatter {
                title
              }
              fields {
                slug  
              }
            }
            node {
                fields {
                    slug
                  }
              frontmatter {
                title
              }
            }
          }
        }
      }

node が今の記事、next previous がそれぞれ次の、前の記事情報で、今回はパスにした slug を取得しています. これを各記事へ context として渡すため以下のように書き換えます.

gatsby-node.js
 res.data.allMarkdownRemark.edges.forEach( ({node , previous , next}) => {
        createPage({
            component: blogTemplate ,
            path: `/bloglist/${node.fields.slug}` ,
            context: {
                slug: node.fields.slug ,
                previous ,
                next
            }
        })
    })

ここで、なぜ edges.next.fields.slug のようにしないかというと、記事の一番端に行ってしまうと、>next または previous がそのまま null になってしまうため、fieldsにたどり着けず、エラーにな>るからです.

blog-template.js にて contextを渡してあげましょう.

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

export const query = graphql`
    query ( $slug: String! ) {
      markdownRemark (fields: { slug: { eq: $slug } }) {
        frontmatter {
            title
            date(formatString: "MMMM DD, YYYY")
        }
        html
    }
}
`

const Blog = (props) => {
+    const { previous, next } = props.pageContext
    return (
        <Layout>
            <h1>{props.data.markdownRemark.frontmatter.title}</h1>
            <p>{props.data.markdownRemark.frontmatter.date}</p>
            <div dangerouslySetInnerHTML={{ __html: props.data.markdownRemark.html}}></div>
 //追加ここから
            <ul>
              <li>
                  {previous && (
                  <Link to={`/blog/${previous.fields.slug}`} className="arrow-link">
                    <strong className="ring">Previous</strong> <br/>
                      <h4>{previous.frontmatter.title}</h4>
                   </Link>
                  )}
                </li>
                <li>
                  {next && (
                    <Link to={`/blog/${next.fields.slug}`} className="arrow-link">
                    <strong className="ring">Next</strong> <br/>
                      <h4>{next.frontmatter.title}</h4>
                    </Link>
                  )}
                </li> 
              </ul>
//追加ここまで
        </Layout>
    )
}

export default Blog

これで記事間のページネーションできるようになりました !

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

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?