如何在Gatsby中通过GraphQL仅获取单个数据元素?
如何在Gatsby中获取并展示单个指定ID的Markdown博客文章
1. 确认GraphQL查询有效性
你写的查询逻辑是正确的,它会精准匹配ID为9ac19d6d的Markdown文章数据。和之前获取列表的场景不同,单条查询返回的是单个对象,不需要使用.map(.map是用来遍历数组的),直接读取对象属性即可渲染。
2. 静态页面(固定ID)实现示例
如果你的需求是展示固定ID的文章,直接在页面组件中使用页面查询获取数据,然后渲染内容:
import React from "react" import { graphql } from "gatsby" // 单个博客页面组件 const SingleBlog = ({ data }) => { // 直接从data中取出单篇文章对象 const post = data.markdownRemark return ( <div className="single-post-container"> <h1>{post.title}</h1> <p className="post-description">{post.description}</p> {/* Markdown内容会被编译为HTML字符串,用dangerouslySetInnerHTML渲染 */} <div className="post-content" dangerouslySetInnerHTML={{ __html: post.content }} /> </div> ) } // 页面级GraphQL查询 export const query = graphql` query SinglePostQuery { markdownRemark(id: {eq: "9ac19d6d"}) { title description content } } ` export default SingleBlog
3. 动态路由(根据URL参数获取)
如果需要根据URL中的ID动态加载文章(比如/blog/9ac19d6d),需要使用带变量的查询,并在gatsby-node.js中生成动态页面:
页面组件代码
import React from "react" import { graphql } from "gatsby" const DynamicSingleBlog = ({ data }) => { const post = data.markdownRemark return ( <div className="single-post-container"> <h1>{post.title}</h1> <p className="post-description">{post.description}</p> <div className="post-content" dangerouslySetInnerHTML={{ __html: post.content }} /> </div> ) } // 带变量的查询,$id会从路由参数中获取 export const query = graphql` query DynamicSinglePostQuery($id: String!) { markdownRemark(id: {eq: $id}) { title description content } } ` export default DynamicSingleBlog
在gatsby-node.js中生成动态页面
exports.createPages = async ({ graphql, actions }) => { const { createPage } = actions // 获取所有Markdown文章数据 const result = await graphql(` query { allMarkdownRemark { nodes { id } } } `) // 为每篇文章生成动态页面 result.data.allMarkdownRemark.nodes.forEach(node => { createPage({ path: `/blog/${node.id}`, component: require.resolve("./src/templates/single-blog.js"), // 你的页面组件路径 context: { id: node.id, // 将ID作为上下文参数传递给查询 }, }) }) }
关键区别说明
你之前获取列表的代码中,数据是data.allMarkdownRemark.nodes(一个数组),所以需要用.map遍历;而单篇文章的查询返回的是data.markdownRemark(单个对象),直接访问其属性即可完成渲染。
内容的提问来源于stack exchange,提问作者Devraj Parida
相关产品推荐
相关产品推荐

