Gatsby 使用 slug 查询特定帖子

Posted

技术标签:

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

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

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

这是下面代码的逻辑:

    在我的过滤器中指定 slug 然后eq(等于)变量$slug 上述变量将允许我动态过滤,而不是手动查询后端中的每个帖子 然后我用data.sanityPosts.Title查询前端的数据 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 未定义?我怎样才能更好地解决这个问题?

【问题讨论】:

【参考方案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@字段命名。

【讨论】:

以上是关于Gatsby 使用 slug 查询特定帖子的主要内容,如果未能解决你的问题,请参考以下文章

在 Gatsby 中从 graphQL 查询创建 slug

Gatsby:在自定义帖子类型上使用 GraphQL 查询和自定义分类

引用 Gatsby 模板中查询中使用的 GraphQL 变量?

来自 markdown 帖子的 Gatsby 图像未从 graphql 查询中显示

如何改进对特定图像的 gatsby 图像查询

如何通过 GraphQL 的“slug”查询我的 API 以获取单个实体?