如何通过GraphQL获取JSON数据在Gatsby创建动态页面及报错处理
错误原因
allJson.edges是数组类型,每个元素才是包含node属性的对象,直接对数组调用.node肯定会返回undefined,触发报错。- 你的GraphQL查询中声明了要拉取
example字段,但本地JSON里根本没有这个字段,只有id和title,后续渲染也会出问题。 - 页面组件直接接收的参数是整个props对象,查询结果存在props的
data属性下,原代码没有做解构,取值路径本身就错误。
正确遍历写法
第一步:修正GraphQL查询
把不存在的example字段替换为JSON里实际存在的title,并且要按Gatsby页面查询的规范导出查询:
import { graphql } from 'gatsby' // Gatsby页面查询必须导出 export const query = graphql` query MyQuery { allJson { edges { node { compdata { id title } } } } } `
第二步:修正index.js取值逻辑
export default function Home({ data }) { // 因为只有一个data.json文件,edges数组只有1项,取索引为0的元素再拿node const compdata = data.allJson.edges[0].node.compdata return ( <Layout> <h1>Home page</h1> <ul> {/* 建议用数据本身的id做key,比index更稳定 */} {compdata.map((item) => { return <li key={`content_item_${item.id}`}>{item.title}</li> })} </ul> </Layout> ) }
基于JSON创建动态页面的方法
你需要在项目根目录的gatsby-node.js文件中编写页面生成逻辑:
第一步:编写gatsby-node.js逻辑
exports.createPages = async ({ graphql, actions }) => { const { createPage } = actions // 先查询JSON数据 const result = await graphql(` query { allJson { edges { node { compdata { id title } } } } } `) // 拿到compdata数组 const compdata = result.data.allJson.edges[0].node.compdata // 遍历每一项数据生成独立页面 compdata.forEach(item => { createPage({ // 自定义页面路径,这里用id做路由参数 path: `/comp/${item.id}`, // 指定页面使用的模板组件,需要提前创建 component: require.resolve("./src/templates/comp.js"), // 传给模板的上下文参数,模板内可以直接读取 context: { id: item.id, title: item.title }, }) }) }
第二步:创建页面模板
新建src/templates/comp.js作为动态页面的模板:
const CompTemplate = ({ pageContext }) => { // 从pageContext中拿到gatsby-node传过来的参数 const { id, title } = pageContext return <div> <h1>{title}</h1> <p>当前内容id:{id}</p> </div> } export default CompTemplate
修改完成后重启Gatsby开发服务即可生效。
内容的提问来源于stack exchange,提问作者shaikh
相关产品推荐
相关产品推荐

