I have a component that works as a collapsible ui element where an image is loaded when opened. These collapsible elements are part of a list, and I need the image to be a variable since it's different on each list item.
I understand that I need to use Dynamic Images in Gatsby, since Static Images can't use props, and I need to resolve the image name from a prop.
Trying to use Dynamic Image, I'm getting "undefined" when trying to resolve the image from a prop. According to this post, you can't use GraphQL inside a component that is not in the /pages directory. Instead they are suggesting the use of Fragment, and that's where I'm stuck trying to figure out how to use it in my specific case.
Here's what I'm trying to do in src/components/Collapsible.js:
import React, { useState } from "react";
import { GatsbyImage } from "gatsby-plugin-image";
function Collapsible({ hit, children }) {
const [isOpen, setIsOpen] = useState(false);
const image = "../images/reference/render/" + hit.name;
return !isOpen ? (
<tr className="row" onClick={() => setIsOpen(!isOpen)}>
{children}
</tr>
) : (
<tr>
<td colSpan="4">
<div className="material-card">
<div>
<h1 onClick={() => setIsOpen(!isOpen)}>{hit.name}</h1>
<p>{hit.category}</p>
<div className="thumbnail">
<GatsbyImage image={image}/>
</div>
</div>
</div>
</td>
</tr>
);
}
export default Collapsible;
Somehow I'm supposed to be able to create a Fragment using my GraphQl query, which looks like this:
query Image {
file(relativePath: {eq: "reference/render/image1.png"}) {
id
childImageSharp {
gatsbyImageData(
width: 300
placeholder: NONE
quality: 75
layout: CONSTRAINED
)
}
}
}
Any ideas?
This line:
Is returning a path, while when using
GatsbyImageyou need to provide a full object withgatsbyImageDataas animageproperty. The approach will work when rendering "standard"<img>in thesrcattribute but not withGatsbyImagesince yourimagevariable doesn't contain the data thatGatsbyImageneeds.Moreover, your GraphQL query fragment I'm not sure where it's used, but not in any snippet you've shared. The problem here is that you are trying to combine dynamic images with static queries, where you can't use dynamic filters:
hit.namewill be something dynamic and you cannot combine it with static queries hence they don't accept dynamic parameters.That said, I think a valid workaround will be using a useStaticQuery hook to get
allFilenode withgatsbyImageDatain it and filter the array usinghit.nameor with therelativePath.allFilewill hold all your images so that you only need to filter it using JavaScript.Note: Test the query in the
localhost:8000/___graphqlbefore to ensure that the query is returning the correct data. Tweak thenode => node.relativePath === "../images/reference/render/" + hit.nameto match your specific filter, this is an example.The static query will hold your data inside
data.allFile, there, usinghit.nameyou can filter the array of images and get the needed one. This image, since it's queried and holdinggatsbyImageData, will be a valid image to use inGatsbyImage