【问题标题】:Gatsby Query for specific post using slugGatsby 使用 slug 查询特定帖子
【发布时间】:2021-06-10 00:59:15
【问题描述】:

我正在尝试使用 slug 查询特定的博客帖子 - 以便根据 slug 显示特定的帖子

我遇到了以下错误:TypeError: Cannot read property 'Title' of null

这是下面代码的逻辑:

  1. 在我的过滤器中指定 slug
  2. 然后eq(等于)变量$slug
  3. 上述变量将允许我动态过滤,而不是手动查询后端中的每个帖子
  4. 然后我用data.sanityPosts.Title查询前端的数据
  5. Title 由于某种原因未定义
export const query = graphql` {
sanityPosts(slug: {current: {eq: "$slug"}}) {
    Title
  }
}
`;

const singlePost = ({ data }) => (
    <Layout>
        <Header />
        <div>
        <h1>{data.sanityPosts.Title}</h1>
        </div>
        <Footer />
    </Layout>
)

export default singlePost

为什么Title 未定义?我怎样才能更好地解决这个问题?

【问题讨论】:

    标签: reactjs graphql content-management-system gatsby sanity


    【解决方案1】:

    您的组件应如下所示:

    export const query = graphql` {
    sanityPosts(slug: {current: {eq: "$slug"}}) {
        Title
      }
    }
    `;
    
    const SinglePost = ({ data }) => (
        <Layout>
            <Header />
            <div>
            <h1>{data.sanityPosts.Title}</h1>
            </div>
            <Footer />
        </Layout>
    )
    
    export default SinglePost
    

    注意SinglePost 中大写的S

    也就是说,将$slug 传递给模板/页面组件的唯一方法是使用上下文API,这基本上就是您在gatsby-node.js 中所做的。在那里,您应该查询所有帖子并在遍历它们以创建动态页面时使用 createPages API。在那里,您将公开每个帖子的上下文,并且您可以告诉 Gatsby 该模板的位置以便传递数据。

    答案缺乏信息,但解决方法应如下所示:

    const path = require(`path`)
    const { createFilePath } = require(`gatsby-source-filesystem`)
    exports.onCreateNode = ({ node, getNode, actions }) => {
      const { createNodeField } = actions
      if (node.internal.type === `MarkdownRemark`) {
        const slug = createFilePath({ node, getNode, basePath: `pages` })
        createNodeField({
          node,
          name: `slug`,
          value: slug,
        })
      }
    }
    exports.createPages = async ({ graphql, actions }) => {
      const { createPage } = actions
      const result = await graphql(`
        query {
          allMarkdownRemark {
            edges {
              node {
                fields {
                  slug
                }
              }
            }
          }
        }
      `)
      result.data.allMarkdownRemark.edges.forEach(({ node }) => {
        createPage({
          path: node.fields.slug,
          component: path.resolve(`./src/templates/blog-post.js`),
          context: {
            // Data passed to context is available
            // in page queries as GraphQL variables.
            slug: node.fields.slug,
          },
        })
      })
    }
    

    注意:当然,为你的 Sanity one 调整降价方法 (allMarkdownRemark)

    现在您可以访问模板中的slug

    import React from "react"
    import { graphql } from "gatsby"
    import Layout from "../components/layout"
    
    export default function BlogPost({ data }) {
      const post = data.markdownRemark
      return (
        <Layout>
          <div>
            <h1>{post.frontmatter.title}</h1>
            <div dangerouslySetInnerHTML={{ __html: post.html }} />
          </div>
        </Layout>
      )
    }
    export const query = graphql`
      query($slug: String!) {
        markdownRemark(fields: { slug: { eq: $slug } }) {
          html
          frontmatter {
            title
          }
        }
      }
    `
    

    注意:再次,为你的理智替换降价方法

    您可以按照 Gatsby 文档中的完整指南:https://www.gatsbyjs.com/docs/tutorial/part-seven/

    请记住,您已经在localhost:8000/___graphql 公开了 GraphQL 操场以测试您的查询,以便了解字段的命名方式或嵌套结构的外观,这将使您知道@ 987654332@字段命名。

    【讨论】:

      猜你喜欢
      • 2013-02-05
      • 2020-07-16
      • 1970-01-01
      • 2021-07-03
      • 1970-01-01
      • 2017-06-01
      • 2019-09-23
      • 1970-01-01
      • 2023-03-20
      相关资源
      最近更新 更多