[英]React / Gatsby dynamic background images in a component
I've got a React component that essentially does related content, showing a user the next / prev pieces of content inside of a site. 我有一个React组件,它基本上可以处理相关内容,向用户显示网站内的下一个/上一页内容。
This component needs to import background images so I can use them as inline styles inside of the component. 此组件需要导入背景图像,以便我可以将它们用作组件内部的内联样式。 However, to know which background image I want to import, I have to look at the props which get defined like this:
但是,要知道我要导入哪个背景图像,我必须查看定义如下的道具:
<LocationRelated
previousLocationName="Columbus, OH"
previousLocationPath="columbus"
nextLocationName="St. Pete Beach, FL"
nextLocationPath="st-pete-beach"
/>
But, as far as I can tell, there isn't a way to look at the props of a component before it enters React's render
function - thus no way to do a dynamic import. 但是,据我所知,在进入React的
render
函数之前,没有办法查看组件的道具 - 因此无法进行动态导入。
This is my broken attempt at doing this, using an ES6 template literal inside of the import: 这是我在执行此操作时的破坏尝试,使用导入内部的ES6模板文字:
import React from "react"
import pfbRelatedPrevBGImagePath from '`../../images/grid/PFB_${this.props.previousLocationPath}.jpg`'
import pfbRelatedNextBGImagePath from '`../../images/grid/PFB_${this.props.nextLocationPath}.jpg`'
class LocationRelated extends React.Component {
render() {
const pfbRelatedPrevBG = {
backgroundImage: `linear-gradient( to bottom, rgba(1,1,1,0.2), rgba(2,2,2,0.2) ), url(${ pfbRelatedPrevBGImagePath })`
}
const pfbRelatedNextBG = {
backgroundImage: `linear-gradient( to bottom, rgba(1,1,1,0.2), rgba(2,2,2,0.2) ), url(${ pfbRelatedNextBGImagePath })`
}
return (
<div>
<aside className="pfb-longform-container">
<section className="pfb-related-content">
<h3 className="pfb-related-content-title">Additional Locations</h3>
<section className="pfb-related-image-container">
<div
className="pfb-related-1"
style= { pfbRelatedPrevBG }
>
<p className="pfb-related-text">{ this.props.previousLocationName }</p>
</div>
<div
className="pfb-related-2"
style= { pfbRelatedNextBG }
>
<p className="pfb-related-text">{ this.props.nextLocationName }</p>
</div>
</section>
</section>
</aside>
</div>
)
}
}
export default LocationRelated
My webpack builder errors out, saying basically it can't read this.props.whatever
because it hasn't been defined yet when it tries to read the import
. 我的webpack构建器出错了,说基本上它无法读取
this.props.whatever
因为它在尝试读取import
this.props.whatever
未定义。 Is there a way to do this? 有没有办法做到这一点?
Additional note: I'm using the Gatsby static site generator for this site, but that shouldn't really impact what's happening (at least I don't think it should). 附加说明:我正在为此站点使用Gatsby静态站点生成器,但这不应该真正影响正在发生的事情(至少我认为不应该)。
The above approach is impossible as best I can tell, but as I discovered, it's impossible for a good reason. 我认为上述方法是不可能的,但正如我发现的那样,这是不可能的。 You have to FULLY give into the React (Gatsby) way of doing things and my approach above was trying to do this from a Drupal/WordPress-CMS-build perspective.
你必须完全放弃React(Gatsby)的做事方式 ,我上面的方法试图从Drupal / WordPress-CMS-build的角度来做这件事。
Check out my revised component for LocationRelated
: 查看我修订的
LocationRelated
组件:
import React from "react"
import Link from 'gatsby-link'
class LocationRelated extends React.Component {
render() {
// Setup inline style objects using ES6 template literals which pull in the correct paths from the content pages themselves
const pfbRelatedPrevBG = {
backgroundImage: `linear-gradient( to bottom, rgba(1,1,1,0.2), rgba(2,2,2,0.2) ), url(${ this.props.prevLocationImgPath.sizes.src })`
}
const pfbRelatedNextBG = {
backgroundImage: `linear-gradient( to bottom, rgba(1,1,1,0.2), rgba(2,2,2,0.2) ), url(${ this.props.nextLocationImgPath.sizes.src })`
}
return (
<div className="pfb-related-bg-container">
<aside className="pfb-related-container">
<section className="pfb-related-content">
<section className="pfb-related-image-container">
<Link
to={ this.props.prevLocationPath }
className="pfb-related-left-arrow"
>
<img src= { LeftArrow } alt="Navigate to the previous location in the PFB Annual Report" />
<div className="pfb-related-left-arrow-text">Previous</div>
</Link>
<Link
to={ this.props.prevLocationPath }
className="pfb-related-1"
style={ pfbRelatedPrevBG }
>
<p className="pfb-related-text">{ this.props.prevLocationName }</p>
</Link>
<Link
to={ this.props.nextLocationPath }
className="pfb-related-2"
style= { pfbRelatedNextBG }
>
<p className="pfb-related-text">{ this.props.nextLocationName }</p>
</Link>
<Link
to={ this.props.nextLocationPath }
className="pfb-related-right-arrow"
>
<img src= { RightArrow } alt="Navigate to the next location in the PFB Annual Report" />
<div className="pfb-related-right-arrow-text">Next</div>
</Link>
</section>
</section>
</aside>
</div>
)
}
}
export default LocationRelated
You'll notice not much is different than the above attempt but pay attention to the this.props.nextLocationImgPath.sizes.src
path being used in the backgroundImage
object literal. 您会注意到与上述尝试没有太大区别,但要注意
backgroundImage
对象文字中使用的this.props.nextLocationImgPath.sizes.src
路径。 You have to pass backgroundImage
the source path as a prop. 您必须将
backgroundImage
作为道具传递给源路径。 Don't try to do it in the component like I was. 不要试图像我一样在组件中这样做。 React's separation of concerns is about getting data out of components and instead feeding data in through props.
React关注点的分离是关于从组件中获取数据,而是通过props提供数据。
So then the question becomes: if you have to pass the path in as a prop, how do you get the path when you call your component at the page level? 那么问题就变成了:如果你必须将路径作为道具传递,那么当你在页面级别调用组件时,如何获得路径?
If you're using Gatsby
(and you should), you need to use GraphQL to get the optimized image paths. 如果你正在使用
Gatsby
(你应该),你需要使用GraphQL来获得优化的图像路径。 In my example, we will call for background-image
path on the same page where we would call the LocationRelated
component. 在我的示例中,我们将在我们调用
LocationRelated
组件的同一页面上调用background-image
路径。
Simplified example of my page that concentrates on the issue at hand: 我的页面的简化示例专注于手头的问题:
import React from 'react'
import Img from "gatsby-image";
import LocationRelated from '../components/LocationRelated'
class CharlotteLocation extends React.Component {
render() {
return (
<div>
<LocationRelated
prevLocationName="Detroit"
prevLocationPath="detroit"
prevLocationImgPath= { this.props.data.charlottePrevImage }
nextLocationName="Montana"
nextLocationPath="montana"
nextLocationImgPath= { this.props.data.charlotteNextImage }
/>
</div>
)
}
}
export default CharlotteLocation
// GraphQL queries for each image
export const CharlotteImageQuery = graphql`
query CharlotteImageQuery {
charlottePrevImage: imageSharp(id: { regex: "/PFB_DETROIT/" }) {
sizes(maxWidth: 600 ) {
...GatsbyImageSharpSizes_withWebp
}
},
charlotteNextImage: imageSharp(id: { regex: "/PFB_MONTANA/" }) {
sizes(maxWidth: 600 ) {
...GatsbyImageSharpSizes_withWebp
}
}
}
`
These GraphQL queries make available the optimized paths to the files we need, and now we can send them into our LocationRelated
component via this.props.data
. 这些GraphQL查询提供了我们所需文件的优化路径,现在我们可以通过
this.props.data
将它们发送到我们的LocationRelated
组件。
gatsby-image
and GraphQL are a bit tricky to work with at first so check out this nice tutorial by Kyle Gill . gatsby-image
和GraphQL起初使用起来有点棘手,所以请查看Kyle Gill的这个精彩教程 。 It got me going a bit better than the Gatsby documentation did. 它让我比Gatsby文档做得更好。
For reference, here is how I set up my gatsby-config.js
in the project to get all these plugins working nicely together (I'm pulling the images from a standalone images
directory in my project rather than in a component, so I needed gatsby-source-filesystem
to make all this work along with gatsby-image
, gatsby-transformer-sharp
, gatsby-plugin-sharp
,): 作为参考,这里是我如何在项目中设置我的
gatsby-config.js
以使所有这些插件很好地协同工作(我从我项目中的独立images
目录而不是组件中提取图像,所以我需要gatsby-source-filesystem
使这一切与gatsby-image
一起工作, gatsby-transformer-sharp
, gatsby-plugin-sharp
,):
module.exports = {
siteMetadata: {
title: 'PFB2017 Site',
},
//pathPrefix: "/pfb2017-site",
plugins: [
// Adds in React Helmet for metadata
`gatsby-plugin-react-helmet`,
// Gives us sass in the project
`gatsby-plugin-sass`,
// This plugin transforms JSON, which is how we are storing our location data
`gatsby-transformer-json`,
// Adds in Gatsby image handling
`gatsby-image`,
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
/**
* This is how you customize gatsby-source-filesystem
* Check this page out for more background
* https://www.gatsbyjs.org/docs/building-with-components
* By default, the gatsby-default starter kit comes with the `pages` directory wired up
* I'm adding it here for consistency but you don't need it
* What I have added into the starter are `images` and `data`, subfolders we'll need for the PFB project
*
*/
{
resolve: `gatsby-source-filesystem`,
options: {
name: `pages`,
path: `${__dirname}/src/pages`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `data`,
path: `${__dirname}/src/data`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`
}
}
],
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.