首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有动态图像源的可重用Gatsby-Image组件

具有动态图像源的可重用Gatsby-Image组件
EN

Stack Overflow用户
提问于 2019-03-12 21:33:41
回答 4查看 12.3K关注 0票数 32

我正在考虑在我的下一个项目中使用Gatsby-Image,并一直在使用它。

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

代码语言:javascript
复制
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

我的最佳用例是向Gatsby.config文件中定义的relativePath发出动态请求,然后组合每个Gatsby中的src prop,并将其与我的资产文件中的所有图像进行匹配,然后显示它。你们中有谁知道这是不是可以用?

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

希望我已经说清楚了。如果你有任何问题,请提出来。

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

先谢谢你,埃里克

EN

回答 4

Stack Overflow用户

发布于 2019-06-09 01:54:59

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

最后的代码:

代码语言:javascript
复制
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;

使用图像:

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

解释

因为StaticQuery在其模板文字中不支持字符串插值,所以我们不能真正向它传递任何属性。相反,我们将尝试在StaticQuery的Render部分处理对props的检查。

注意事项

我不能百分之百确定这是否会影响编译时间,因为我们正在扫描所有的图像。如果是这样,请让我知道!

更新:如果您有许多图像,包大小可能会变得相当大,因为此解决方案会扫描所有图像。

进一步定制

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

替代方案

这就是说,there is another way you could tackle this,但需要更多的工作/代码。

资料来源

  • 我修改了this article中的代码。(请注意,本文使用的是过时的代码。)
票数 44
EN

Stack Overflow用户

发布于 2019-10-08 23:45:05

不幸的是,从我收集到的信息来看,最好的解决方案是为图像编写单独的js文件。

在@RodrigoLeon的方法中,它将导致捆绑包大小急剧增加。特别是当你有超过50张图片的时候。因为每当您使用它并遍历所有图像时,都会在组件文件中创建对它们的引用。所以我不推荐这样做。

票数 10
EN

Stack Overflow用户

发布于 2020-06-19 12:06:47

我正在建设的网站是一个电子商务平台,有数千张图片(适用于所有产品)。这给使用gatsby查询图像带来了一个主要问题。在很长一段时间里,我有一个组件可以查询所有图像,并将它们与各自的产品进行匹配。(就像这里提出的那样)这是非常低效的,会抛出关于查询持续时间的警告。

另一种方法是在数据级别将imageFile附加到产品,而不是在尝试呈现时。

src/gatsby-api/create-resolvers/index.js

代码语言:javascript
复制
const resolvers = {
    AWSAppSync_Product: {
        imageFile: {
            type: 'File',
            resolve: async (source, args, context, info) => {
                const node = await context.nodeModel.runQuery({
                    query: {
                        filter: {
                            Key: { eq: source.image1 }
                        }
                    },
                    type: 'S3Object',
                    firstOnly: true
                });

                if (node && node.imageFile) return node.imageFile;
            }
        },
    },
}

module.exports = {
    resolvers
}

gatsby-node.js

代码语言:javascript
复制
exports.createResolvers = async ({ createResolvers }) => {
    createResolvers(resolvers)
}

src/component/image/index.js

代码语言:javascript
复制
import React from 'react'
import Img from 'gatsby-image'

export const Image = props => {
  if (props.imageFile && props.imageFile.childImageSharp && props.imageFile.childImageSharp.fluid) {
    return <Img className={props.imgClassName} alt={props.alt} fluid={props.imageFile.childImageSharp.fluid} />;
  }
};

然后像这样使用它:

代码语言:javascript
复制
<Image
  imageFile={product.imageFile}
  alt=""
/>

AWSAppSync_Product是我要将文件附加到的节点类型。(可以在localhost上的graphql游乐场中找到)。解析将匹配S3ObjectKey和产品上的image1 (这是一个字符串)。这允许我直接使用产品图像,而不必在图像组件中运行查询。

在我看来,这是一条有价值的信息,一旦你仔细考虑它,它肯定对我有很大的帮助。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55122752

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档