首页 > 解决方案 > 如何将变量添加到 GraphQL 文件查询

问题描述

我正在使用该gatsby-image插件在我的 Gatsby 网站上显示图像。在我的 GraphQL 查询中,我希望能够将一个变量传递给relativePath参数,因为该查询正在(在父组件中)为许多需要图像的组件运行。我似乎无法弄清楚如何做到这一点。

这是我的查询的样子:

...

const imgData = useStaticQuery(graphql`
        query{
            file(relativePath: {eq: "talent.png"}) {
                childImageSharp {
                    fixed (width: 289, height: 589) {
                        ...GatsbyImageSharpFixed
                    }
                }
            }
        }
    `)

我想用一个变量替换那个“talent.png”,这样我就可以跨组件使用这个查询。这是我想要的查询:

const imgData = useStaticQuery(graphql`
        query($pageImg: String!){
            file(relativePath: {eq: $pageImg}) {
                childImageSharp {
                    fixed (width: 289, height: 589) {
                        ...GatsbyImageSharpFixed
                    }
                }
            }
        }
    `)

我尝试使用onCreatePagein向页面添加上下文gatsby-node.js。这适用于页面查询,但文件节点显然无法识别页面上下文。所以我尝试向文件节点添加上下文:

module.exports.onCreateNode = ({ node, actions }) => {
    const { createNodeField } = actions

    if(node.internal.type === 'File'){
        createNodeField({
            node,
            name: 'context',
            value: {
                pageImg: node.relativePath
            }
        })
    }
}

但我仍然收到此错误: Variable "$pageImg" of required type "String!" was not provided.

任何有助于理解如何解决此问题的帮助将不胜感激。

标签: graphqlgatsby

解决方案


我将一个项目从 Nextjs 转换为 Gatsby 主要是因为 gatsby 提供了很酷的插件,所以我遇到了同样的问题,因为我喜欢 gatsby-image 预渲染图像的方式。

我遇到了这个问题,但我不得不重构它以使用新的useStaticQuery钩子,所以你的最终代码应该是这样的:

import React from "react";
import { useStaticQuery, graphql } from "gatsby";
import Img from "gatsby-image";

const Image = ({ style, alt, src, className }) => {
  const data = useStaticQuery(graphql`
    query {
      images: allFile {
        edges {
          node {
            relativePath
            name
            childImageSharp {
              fluid(maxWidth: 600) {
                ...GatsbyImageSharpFluid
              }
            }
          }
        }
      }
    }
  `);

  const image = data.images.edges.find(img => img.node.relativePath.includes(src));
  if (!image) return null;

  return <Img fluid={image.node.childImageSharp.fluid} alt={alt} style={style} className={className} />;
};

使用Image组件:

import Image from '../components/image'
<Image
    src="gatsby-astronaut.png"
    alt="astronaut"
    className="w-full hidden md:block lg:-ml-8 rounded shadow-xl z-10"
/>

推荐阅读