javascript - 具有动态图像源的可重用 Gatsby-Image 组件
问题描述
我正在考虑在我的下一个项目中使用 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
我的最佳用例是向我的 Gatsby.config 文件中定义的 relativePath 发出动态请求,然后将每个 Gatsby 中的 src 道具组合起来,并将其与我的资产文件中的所有图像匹配,然后显示它。你们中的任何人都知道这是否可能?
我在文档中读到静态查询不能接受变量——只有页面。但是我不希望我的图像与页面相关联——我想在任何我想要的地方使用这个组件——就像一个常规的 img 标签。
希望我已经说清楚了。请询问您是否有任何问题。
这是一个例子: https ://codesandbox.io/s/py5n24wk27
预先感谢,埃里克
解决方案
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.)
推荐阅读
- python - 如何让不和谐机器人对过去的私人消息做出反应?
- swagger - Swagger - 如何在响应组件中定义 byte[][]
- c - 检测是否存在任何其他线程的方法(例如,在 fork 之前)
- javascript - 客户端的打字稿模块-最好的方法是什么?
- spring - java.lang.IllegalArgumentException:参数值 [232cb466-6af9-4d7e-85ec-cc72c310d7fd] 与预期类型 [java.util.UUID] 不匹配
- c++ - 构造函数的 C++ 直接和复制初始化问题
- python - python安装后看不到ActiveTcl
- cplex - CPLEX OPL IP 间隙在主块中并在模型中执行
- java - 根据 JFrame 的大小更改 JPanel 组件的大小
- javascript - 单击时如何将搜索结果添加到文本框(如多选框(药盒))