Gatsby - 在 gatsby-node.js 中添加带有参数的 GraphQL 查询

Gastby - Add a GraphQL query with parameters in gastby-node.js

gatsby-node.js 我有两个从 Contentful 获取数据的查询。我想添加一个新查询,根据其 slug(在 Contentful 的内容模型中设置的字段)加载特定内容的数据。

这是我的:

  return graphql(
    `
      {
        allContentfulBlogPost {
          edges {
            node {
              id
              slug
            }
          }
        }
        allContentfulCaseStudy(filter: { slug: { ne: "dummy-content" } }) {
          edges {
            node {
              id
              slug
            }
          }
        }
        contentfulCaseStudy(slug: { eq: $slug }) { // <=== Here is the problem
          title
          overview
        }
      }
    `
  )
    .then(result => {
      if (result.errors) {
        console.log("Error retrieving contentful data", result.errors)
      }
    })
    .catch(error => {
      console.log("Error retrieving contentful data", error)
    })
}

所以,我想查询在 contentfulCaseStudy(slug: { eq: $slug }) 中传递 slug 的特定案例研究,但它不起作用。当我开始 npm run develop:

时它抛出这个错误
 ERROR #85901  GRAPHQL

There was an error in your GraphQL query:

Variable "$slug" is not defined.

File: gatsby-node.js:13:10

Error retrieving contentful data [
  GraphQLError: Variable "$slug" is not defined.
      at Object.leave (C:\Edited\edited\edited\edited\node_modules\graphql\validation\rules\NoUndefinedVariables.js:38:33)
      at Object.leave (C:\Edited\edited\edited\edited\node_modules\graphql\language\visitor.js:345:29)
      at Object.leave (C:\Edited\edited\edited\edited\node_modules\graphql\language\visitor.js:395:21)
      at visit (C:\Edited\edited\edited\edited\node_modules\graphql\language\visitor.js:242:26)
      at validate (C:\Edited\edited\edited\edited\node_modules\graphql\validation\validate.js:73:24)
      at GraphQLRunner.validate (C:\Edited\edited\edited\edited\node_modules\gatsby\dist\query\graphql-runner.js:79:44)
      at GraphQLRunner.query (C:\Edited\edited\edited\edited\node_modules\gatsby\dist\query\graphql-runner.js:144:25)
      at C:\Edited\edited\edited\edited\node_modules\gatsby\dist\bootstrap\create-graphql-runner.js:40:19
      at Object.exports.createPages (C:\Edited\edited\edited\edited\gatsby-node.js:13:10)
      at runAPI (C:\Edited\edited\edited\edited\node_modules\gatsby\dist\utils\api-runner-node.js:259:37)
      at Promise.catch.decorateEvent.pluginName (C:\Edited\edited\edited\edited\node_modules\gatsby\dist\utils\api-runner-node.js:378:15)
      at Promise._execute (C:\Edited\edited\edited\edited\node_modules\bluebird\js\release\debuggability.js:384:9)
      at Promise._resolveFromExecutor (C:\Edited\edited\edited\edited\node_modules\bluebird\js\release\promise.js:518:18)
      at new Promise (C:\Edited\edited\edited\edited\node_modules\bluebird\js\release\promise.js:103:10)
      at C:\Edited\edited\edited\edited\node_modules\gatsby\dist\utils\api-runner-node.js:377:12
      at tryCatcher (C:\Edited\edited\edited\edited\node_modules\bluebird\js\release\util.js:16:23) {
    locations: [ [Object], [Object] ]
  }

是否可以请求将 slug 作为参数传递的特定案例研究?如果有,是怎么做到的?

简短的回答是你不能直接。您可以使用硬编码参数进行过滤,而不是使用动态预查询值。

但是,您尝试用 $slug 做的是通过 context API.

传递一个变量

您要实现的流程是:

  • allContentfulCaseStudy
  • 的 Contentful 数据中获取并创建页面
  • 使用 contentfulCaseStudyallContentfulCaseStudyslug 过滤每个 contentfulCaseStudy 的查询。

因此,您需要将 contentfulCaseStudy 移动到 template.js 中,像这样修改 gatsby-node.js

exports.createPages = async ({ graphql, actions, reporter }) => {
  const { createPage } = actions

  const result = await graphql(
    `
      {
        allContentfulCaseStudy(filter: { slug: { ne: "dummy-content" } }) {
          edges {
            node {
              id
              slug
            }
          }
        }
      }
    `
  )

  if (result.errors) {
    reporter.panicOnBuild(`Error while running GraphQL query.`)
    return
  }

  const caseStudyTemplate= path.resolve(`src/templates/case-study.js`)

  result.data.allContentfulCaseStudy.edges.forEach(({ node }) => {
    createPage({
      path,
      component: caseStudyTemplate,
      context: {
        slug: node.slug,
      },
    })
  })
}

现在,在您的 case-study.js 中,您可以使用 slug 变量,因为您在 page query 中通过 context 传递它。所以:

import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"

export default function CaseStudy({ data }) {
  const caseStudy= data.contentfulCaseStudy
  return (
    <Layout>
      <div>
        <h1>{caseStudy.title}</h1>
      </div>
    </Layout>
  )
}

export const query = graphql`
  query($slug: String!) {
        contentfulCaseStudy(slug: { eq: $slug }) {
          title
          overview
        }
  }
`

检查你的 localhost:8000/___graphql 游乐场,看看嵌套的 titleoverview 是否在 contentfulCaseStudy 下,或者你是否需要修改查询结构。

进一步阅读: