【问题标题】:Gatsby Pagination for multiple pages [closed]盖茨比分页多页[关闭]
【发布时间】:2020-07-20 22:27:52
【问题描述】:

我见过的大多数 Gatsby 教程都处理单一的分页来源。对于我的网站,我有多个页面使用 GraphQL 过滤不同类别的 160 多篇博客文章。我需要某种方式对每个类别页面进行分页,因此用户不必向下滚动数十篇文章即可到达网站页脚。但是像gatsby-awesome-pagination 这样的在线解决方案只处理单一的分页来源。

是否可以跨多个页面进行分页?我想我必须自定义每个类别页面的 GraphQL 以解决分页所需的每个页面的博客文章的差异?这个想法可能吗?

我的Github

【问题讨论】:

    标签: reactjs graphql gatsby


    【解决方案1】:

    您一针见血,您需要自定义您的页面创建。在你的gatsby-node.js

      const posts = result.data.allMarkdownRemark.edges
      const postsPerPage = 6
      const numPages = Math.ceil(posts.length / postsPerPage)
      Array.from({ length: numPages }).forEach((_, i) => {
        createPage({
          path: i === 0 ? `/blog` : `/blog/${i + 1}`,
          component: path.resolve("./src/templates/blog-list-template.js"),
          context: {
            limit: postsPerPage,
            skip: i * postsPerPage,
            numPages,
            currentPage: i + 1,
          },
        })
      })
    

    上面的代码将根据帖子总数创建一定数量的页面。每个页面都会列出postsPerPage(6) 的帖子,直到剩下的帖子少于postsPerPage(6)。第一个页面的路径是/blog,后面的页面会有一个表单的路径:/blog/2/blog/3

    请记住,您通过上下文将限制和当前页面传递给您的模板。因此,在您的博客模板中,您的查询应如下所示:

      query blogListQuery($skip: Int!, $limit: Int!) {
        allMarkdownRemark(
          sort: { fields: [frontmatter___date], order: DESC }
          limit: $limit
          skip: $skip
        ) {
          edges {
            node {
              fields {
                slug
              }
              frontmatter {
                title
              }
            }
          }
        }
      }
    

    你已经完成了,你只需要在你的组件中添加下一个和上一个按钮/编号,如下所示:

    下一个/上一个按钮:

      const { currentPage, numPages } = this.props.pageContext
        const isFirst = currentPage === 1
        const isLast = currentPage === numPages
        const prevPage = currentPage - 1 === 1 ? "/" : (currentPage - 1).toString()
        const nextPage = (currentPage + 1).toString()
        return (
           /* your code to display a list of posts */
          {!isFirst && (
            <Link to={prevPage} rel="prev">
              ← Previous Page
            </Link>
          )}
          {!isLast && (
            <Link to={nextPage} rel="next">
              Next Page →
            </Link>
          )}
        )
    

    编号:

       const { currentPage, numPages } = this.props.pageContext
        return (
          // ...
          {Array.from({ length: numPages }, (_, i) => (
            <Link key={`pagination-number${i + 1}`} to={`/${i === 0 ? "" : i + 1}`}>
              {i + 1}
            </Link>
          ))}
    

    您可以查看更多详细信息here

    【讨论】:

    • 我有一个关于component: path.resolve("./src/templates/blog-list-template.js"), 的问题因为我的网站结构使用查询不同frontmatter 的多个类别页面,我很困惑如何解决多个不同查询的单个路径。现在我的帖子来自使用markdownRemarkcomponent: path.resolve(./src/templates/blog-post.js),,所以使用以下建议对我来说非常棘手。有没有其他方法可以使用组件而不是模板?然后我可以与我的类别页面共享该组件。
    • 您应该创建相同的结构(循环设置每个页面的最大帖子/标签/任何内容),因为代码运行onCreatePage API,因此,盖茨比必须知道每页必须有多少项目。您可以重用的是分页组件,您可以提取它们并导入它,通过道具将您需要的内容传递给自定义1个组件以进行多次使用。
    • 使用allMarkdownRemark 的博客列表模板的 gatsby 站点建议不太适合我,因为我的博客列表模板没有单一来源,但在 9 上运行的 graphQL 查询略有不同不同的页面。在这种情况下,我并没有真正可以查询的博客列表模板。我只有一个吐出markdownRemark html 的博客文章模板。我希望我说得通。这是我的第一个 gatsby 项目,我对真正可能或不可能的事情有点茫然。
    • 好的,我会试试的,谢谢。因为这是我的第一个 gatsby 项目,所以我不确定我是否正确地解释了事情。现在我将创建一个单独的博客列表模板页面并按照您的建议运行代码。
    • 感谢您的更新。 StaticQuery 也不接受同一组件中的两个调用。恐怕您应该尝试一种中间件,以便首先从源中获取和检索所有帖子,然后解决分页问题。祝你好运。
    猜你喜欢
    • 2021-12-24
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-16
    • 2020-10-16
    • 2019-08-07
    • 2021-12-14
    相关资源
    最近更新 更多