使用 Gatsby Contentful 显示所有博客文章

Displaying all blog posts with Gatsby Contentful

我试图将我所有的 Contentful 博客文章显示到我在 Gatsby 中的索引页面,但出现错误。

我正在 gatsby-node.js 上创建帖子页面,如下所示:

const path = require(`path`)
// Log out information after a build is done
exports.onPostBuild = ({ reporter }) => {
  reporter.info(`Your Gatsby site has been built!`)
}
// Create blog pages dynamically
exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions
  const blogPostTemplate = path.resolve(`src/templates/blogPost.js`)
  const result = await graphql(`
    query {
      allContentfulPost {
        edges {
          node {
            postTitle
            slug
          }
        }
      }
    }
  `)
  result.data.allContentfulPost.edges.forEach(edge => {
    createPage({
      path: `${edge.node.slug}`,
      component: blogPostTemplate,
      context: {
        title: edge.node.postTitle,
        slug: edge.node.slug,
      },
    })
  })
}

基于此模板:

import React from "react"
import { graphql } from "gatsby"
import styled from "styled-components"

export const pageQuery = graphql`
  query($slug: String!) {
    post: contentfulPost(slug: { eq: $slug }) {
      slug
      postTitle
      postContent {
        childMarkdownRemark {
          html
        }
      }
      postImage {
        title
        fluid {
          src
        }
      }
    }
  }
`

function blogPost({ data }) {
  return (
    <div>
      <img
        src={data.post.postImage.fluid.src}
        alt={data.post.postImage.title}
      ></img>
      <h1>{data.post.postTitle}</h1>
      <h3
        dangerouslySetInnerHTML={{
          __html: data.post.postContent.childMarkdownRemark.html,
        }}
      />
    </div>
  )
}

export default blogPost

现在我尝试创建一个组件来保存所有博客文章,这样我就可以在我的 index.js 页面上显示它,如下所示:

import { Link, graphql, StaticQuery } from "gatsby"
import React from "react"
import styled from "styled-components"

function BlogSection() {
  return (
    <StaticQuery
      query={graphql`
        query blogQuery {
          
          allContentfulPost {
            edges {
              node {
                slug
                postTitle
                postImage {
                  file {
                    url
                    fileName
                  }
                }
                postContent {
                  postContent
                }
                postDate
              }
            }
          }
        }
      `}
      render={data => (
        <ul>
          <Link to={data.allContentfulPost.edges.node.slug}> //here's where the error happens
            {data.allContentfulPost.edges.node.postTitle}
          </Link>
        </ul>
      )}
    />
  )
}

export default BlogSection

但是我得到一个错误 Cannot read property 'slug' of undefined 这让我发疯了好几天。

如有任何帮助,我们将不胜感激!

使用:

<ul>
  {data.allContentfulPost.edges.map(({ node }) => {
    return <Link to={node.slug} key={node.slug}>
    {node.postTitle}
  </Link>
  })}
</ul>

您正在查询来自 Contentful (allContentfulPost) 的所有罐子,它遵循嵌套结构,内部有一个 edges 和一个 node:最后一个包含您的所有信息posts(由于嵌套结构,您有 slugpostTitle 等)所以 node 确实是您的 post。也就是说,您只需要遍历 edges,这是您的 post 的数组。在前面的片段中:

data.allContentfulPost.edges.map(({ node })

您在循环遍历可迭代变量的同时解构它 ({ node })。您可以为它取别名以获得更简洁的方法,例如:

<ul>
  {data.allContentfulPost.edges.map(({ node: post }) => {
    return <Link to={post.slug} key={post.slug}>
    {post.postTitle}
  </Link>
  })}
</ul>

在所有循环中使用 key attribute 很重要,因为它将帮助 React 了解哪些元素正在发生变化。