具有动态图像源的可重复使用的盖茨比图像组件

eri*_*s93 8 javascript reactjs graphql gatsby

我正在考虑将Gatsby-Image用于我的下一个项目,并且已经对其进行了一些尝试。

我可以在测试项目中使用它,但是后来我想到了一个用例,我想像常规<img src”image.png”>标记一样使用Gatsby中的。因此,我的问题是如何使Gatsby组件可重用?

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
Run Code Online (Sandbox Code Playgroud)

我的最佳用例是向我的Gatsby.config文件中定义的relativePath发出动态请求,然后将每个Gatsby中的src属性组合起来,并将其与我的资源文件中的所有图像匹配,然后显示它。你们中有人知道这是否可能吗?

我在文档中读到,“静态查询”不能接受变量,只能接受页面。但是我不希望我的图像与页面相关联-我想在任何需要的地方使用此组件-像常规的img标签一样。

希望我已经说清楚了。请询问您是否有任何疑问。

这是一个示例:https : //codesandbox.io/s/py5n24wk27

预先感谢,埃里克

小智 10

不幸的是,据我所知,最好的解决方案是为图像写出单独的 js 文件。

在@RodrigoLeon 的方法中,它会导致包大小显着增加。特别是如果说你有超过 50 张图片。因为无论何时您使用它并遍历所有图像,您都会在组件文件中创建对它们的引用。所以我不建议这样做。


Rod*_*eon 8

我也在寻找这个答案。希望这能回答您的问题:

最终代码:

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;
Run Code Online (Sandbox Code Playgroud)

使用图像:

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

说明

由于StaticQuery在其模板文字中不支持字符串插值,因此我们无法真正传递任何道具。相反,我们将尝试在StaticQuery的“渲染”部分中处理道具检查。

注意事项

由于我们正在扫描所有图像,因此我不确定100%是否会影响编译时间。如果有,请告诉我!

更新:如果您有很多图像,由于此解决方案可以扫描所有图像,因此捆绑包的尺寸可能会很大。

进一步定制

如果未传递任何道具,则可以调整代码以显示占位符图像。

备择方案

也就是说,还有另一种方法可以解决此问题,但需要更多的工作/代码。

资料来源

  • 我修改了本文的代码。(请注意,本文使用的是不推荐使用的代码。)

  • 盖茨比队确实错过了这一球。谁会想到Web开发人员不想为每个图像单独创建查询和组件。/秒 (3认同)