You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Gatsby的GraphQL请求中避免查询代码重复?

解决方案

Gatsby 原生支持通过 GraphQL 片段(Fragment) 实现查询字段复用,完全替代不可用的字符串插值方案,操作步骤如下:

1. 报错原因说明

Gatsby 的 graphql 标签是在构建阶段静态解析的,不支持运行时字符串插值,因此你之前的写法会触发语法错误。

2. 定义公共复用片段

你可以单独新建一个文件存放全局通用的查询片段(比如 src/graphql/fragments/recetteFields.js),把所有需要复用的字段统一维护在这里:

import { graphql } from 'gatsby'

// 单篇食谱的核心字段,所有需要复用的字段都在这里增删
export const recetteCoreFields = graphql`
  fragment RecetteCoreFields on ContentfulRecette {
    id
    nom
    # 后续新增的字段全部加在这里即可
  }
`

// 列表查询的外层 edges 结构,直接复用上面的单篇字段
export const allRecetteListStructure = graphql`
  fragment AllRecetteListStructure on ContentfulRecetteConnection {
    edges {
      node {
        ...RecetteCoreFields
      }
    }
  }
`

注:on 后接的类型可以在本地 Gatsby 的 GraphiQL 调试工具(默认地址 http://localhost:8000/___graphql)的文档栏里查询确认,allContentfulRecette 返回的集合类型默认就是 ContentfulRecetteConnection,单篇内容类型为 ContentfulRecette

3. 改写原有查询直接复用片段

你不需要额外处理片段导入的逻辑,只要项目里存在上述片段定义,所有查询都可以直接调用:

无排序无筛选的查询

graphql(`
  {
    allContentfulRecette {
      ...AllRecetteListStructure
    }
  }
`)

首页带排序的 IndexQuery

graphql`
  query IndexQuery {
    posts : allContentfulRecette(sort: {fields: dateDePublication}){
      ...AllRecetteListStructure
    }
  }
`

分类页带筛选的查询

graphql`
  query allRecettesByCategorie($slug: String!) {
    recettes : allContentfulRecette(
     sort: {fields: dateDePublication}
     filter: {categorie: {elemMatch: {slug: {eq: $slug}}}}
    ) {
      ...AllRecetteListStructure
    }
  }
`

后续你需要修改字段时,仅需要改动最开始定义的 RecetteCoreFields 片段一处,所有引用了该片段的查询会自动同步,完全消除重复维护的成本。


内容的提问来源于stack exchange,提问作者kookoyy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 10:06:03