Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
234 views
in Technique[技术] by (71.8m points)

javascript - Reusable Gatsby-Image Component with dynamic image sources

I’m thinking of using Gatsby-Image for my next project and has been playing around with it a little.

I got it to work on my test project but then I came up with a use case that I would like to use the from Gatsby much like a regular <img src”image.png”> tag. My question is therefore how I can make the Gatsby component reusable?

import React from "react"
import { StaticQuery, graphql } from "gatsby"
import Img from "gatsby-image"
function renderImage({ file }) {
  console.log({ file })
  return <Img fluid={file.childImageSharp.fluid} />
}

// Stateless Image component which i guess will recieve src value as a prop?
// Returns a StaticQuery component with query prop and render prop. Query prop has the graphql query to recieve the images and render prop returns a renderImage function which in return, returns a Img component fr?n Gatsby with set attributes.
const Image = () => (
  <StaticQuery
    query={graphql`
      query {
        file(relativePath: { eq: "gatsby-astronaut.png" }) {
          childImageSharp {
            fluid(maxWidth: 300) {
              ...GatsbyImageSharpFluid
            }
          }
        }
      }
    `}
    // render={data => <Img fluid={data.placeholderImage.childImageSharp.fluid} />}
    render={renderImage}
  />
)
export default Image

My optimal use case would be to make a dynamic request to my relativePath which is defined in my Gatsby.config file and then combine the src prop in each Gatsby and match it with all my images in my assets file and then display it. Do anyone of you know if this is even possible with ?

I read in the docs that Static Query can't take variables - only pages. But I don't want my images to be associated with a page - I want to use this component anywhere I want - like a regular img tag.

Hope I’ve made myself clear. Please ask if you have any questions.

This is an example: https://codesandbox.io/s/py5n24wk27

Thanks beforehand, Erik

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I've been searching for this answer as well. Hopefully this answers your question:

The final code:

import React from 'react';
import { StaticQuery, graphql } from 'gatsby';
import Img from 'gatsby-image';

// Note: You can change "images" to whatever you'd like.

const Image = props => (
  <StaticQuery
    query={graphql`
      query {
        images: allFile {
          edges {
            node {
              relativePath
              name
              childImageSharp {
                fluid(maxWidth: 600) {
                  ...GatsbyImageSharpFluid
                }
              }
            }
          }
        }
      }
    `}
    render={data => {
      const image = data.images.edges.find(n => {
        return n.node.relativePath.includes(props.filename);
      });
      if (!image) {
        return null;
      }

      //const imageSizes = image.node.childImageSharp.sizes; sizes={imageSizes}
      return <Img alt={props.alt} fluid={image.node.childImageSharp.fluid} />;
    }}
  />
);

export default Image;

Using the image:

import Image from '../components/Image';
<div style={{ maxWidth: `300px` }}>
    <Image alt="Gatsby in Space" filename="gatsby-astronaut.png" />
</div>

Explanation

Because StaticQuery doesn't support string interpolation in its template literal, we can't really pass it any props. Instead we will try and handle check for props in the StaticQuery's Render portion.

Caveats

I'm not 100% sure if this affects compiling time since we are scanning all images. If it does, please let me know!

Update: If you have many images, bundle size can get quite large as this solution does scan ALL images.

Further customization

You can adjust the code to show a placeholder image if no props are passed.

Alternatives

That said, there is another way you could tackle this but with a bit more work/code.

Sources

  • I modified the code from this article. (Please note that the article was using deprecated code.)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...