Search code examples
graphqlgatsbygatsby-imagegatsby-plugin

Passing Gatsby Image props from state and GraphQL


I am having problems with GatsbyImage from "gatsby-plugin-image" plugin that I could really use some help with.

I have a reusable component that I created like this:

<section className={this.props.className}> 
  <div className="flexCol summaryStyles">
    <h3 className="boldStyles">{this.props.title}</h3>
    {this.props.copy}
  </div>
  <div className="imagecontainerStyles">
    {this.props.image}
  </div>
</section>

I want to use this reusable component to display different images (inside my src/images folder structure I have a sub folder named "process" where I am going to place multiple images). Inside {this.props.image} I want to pass in a GatsbyImage component like this:

{this.state.map((item, index) =>
  <Process 
    key={index}
    className={item.className}
    title={item.title}
    copy={item.copy}
    image={<GatsbyImage image={item.image} alt={item.alt}></GatsbyImage>}
  >
  </Process>
)}

I have my state setup like this (I only have one item for now but will have multiple items later):

constructor(props) {
    super(props);
    this.state = [
        {
            className: "flexRow flexRowL",
            title: "EXPLORE",
            copy: <p className="pStyles">I did <strong>user interviews</strong> with people that have food allergies to find out what their experiences have been when eating out, specifically ordering food to go.</p>,
            image: this.props.data.pics.edges[0],
            alt: "Explore UI image"
        }
    ];
}

And my GraphQL setup like this:

export const pageQuery = graphql `
    query {
        pics: allFile(filter: {relativeDirectory: {eq: "process"}}) {
            edges {
                node {
                    name
                    childImageSharp {
                        id
                    }
                }
            }
        }
    }
`

The only thing that I'm getting is this: Website Screenshot Preview

I'm not sure what I am doing wrong and if anyone can help or explain I would really appreciate it. I've read through the documentation available on Gatsby and posts here on StackOverflow but I can't seem to figure it out. This is the first time I am using GraphQL.


Solution

  • I think your approach is valid enough to work but I think you are missing the key data in the GraphQL query to allow Gatsby to print your image. It should be something like:

    export const pageQuery = graphql `
        query {
            pics: allFile(filter: {relativeDirectory: {eq: "process"}}) {
                edges {
                    node {
                        name
                        childImageSharp {
                           gatsbyImageData(
                             width: 200
                             placeholder: BLURRED
                             formats: [AUTO, WEBP, AVIF]
                           )
                        }
                    }
                }
            }
        }
    `
    

    Note: of course, tweak and customize the placeholders (or remove it if you want)

    You need to fetch the gatsbyImageData from the image in order to use it as image property in GatsbyImage component.

    Following that, your data should be always gatsbyImageData so:

    image: this.props.data.pics.edges[0],
    

    Should become:

    image: this.props.data.pics.edges.node[0].childImageSharp.gatsbyImageData,
    

    The array is node, not edges so taking the first element (for now) should be in node[0]. Once there, as I said, the needed data is gatsbyImageData so you need to keep nesting until you reach it.