组件中的 React / Gatsby 动态背景图片
React / Gatsby dynamic background images in a component
我有一个 React 组件,它主要执行相关内容,向用户显示站点内的下一个/上一个内容。
此组件需要导入背景图像,以便我可以将它们用作组件内的内联样式。但是,要知道 我想导入哪个 背景图像,我必须查看像这样定义的道具:
<LocationRelated
previousLocationName="Columbus, OH"
previousLocationPath="columbus"
nextLocationName="St. Pete Beach, FL"
nextLocationPath="st-pete-beach"
/>
但是,据我所知,在组件进入 React 的 render
函数之前,没有办法查看组件的 props - 因此无法进行动态导入。
这是我失败的尝试,在导入中使用了 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
我的 webpack 构建器出错了,基本上说它无法读取 this.props.whatever
,因为它在尝试读取 import
时尚未定义。有办法吗?
补充说明:我正在为该站点使用 Gatsby 静态站点生成器,但这不会真正影响正在发生的事情(至少我认为不会)。
据我所知,上述方法是不可能的,但正如我发现的那样,这是有充分理由的。你必须完全接受 React (Gatsby) 的做事方式,而我上面的方法是试图从 Drupal/WordPress-CMS-build 的角度来做到这一点。
查看我为 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
您会注意到与上述尝试没有太大区别,但请注意 backgroundImage
对象文字中使用的 this.props.nextLocationImgPath.sizes.src
路径。您必须将 backgroundImage
源路径作为道具传递。不要像我一样在组件中尝试这样做。 React 的关注点分离是关于从组件中获取数据,而不是通过 props 提供数据。
那么问题就变成了:如果你必须将路径作为prop传入,那么在页面级别调用组件时如何获取路径?
如果您正在使用 Gatsby
(您应该这样做),则需要使用 GraphQL 来获取优化的图像路径。在我的示例中,我们将在调用 LocationRelated
组件的同一页面上调用 background-image
路径。
专注于手头问题的我页面的简化示例:
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
}
}
}
`
这些 GraphQL 查询提供了我们所需文件的优化路径,现在我们可以通过 this.props.data
将它们发送到我们的 LocationRelated
组件中。
gatsby-image
和 GraphQL 一开始使用起来有点棘手,所以请查看 this nice tutorial by Kyle Gill。它让我比 Gatsby 文档做得更好。
作为参考,这里是我如何在项目中设置我的 gatsby-config.js
以使所有这些插件很好地协同工作(我从项目中的独立 images
目录中提取图像而不是在组件中,所以我需要 gatsby-source-filesystem
与 gatsby-image
、gatsby-transformer-sharp
、gatsby-plugin-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`
}
}
],
};
我有一个 React 组件,它主要执行相关内容,向用户显示站点内的下一个/上一个内容。
此组件需要导入背景图像,以便我可以将它们用作组件内的内联样式。但是,要知道 我想导入哪个 背景图像,我必须查看像这样定义的道具:
<LocationRelated
previousLocationName="Columbus, OH"
previousLocationPath="columbus"
nextLocationName="St. Pete Beach, FL"
nextLocationPath="st-pete-beach"
/>
但是,据我所知,在组件进入 React 的 render
函数之前,没有办法查看组件的 props - 因此无法进行动态导入。
这是我失败的尝试,在导入中使用了 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
我的 webpack 构建器出错了,基本上说它无法读取 this.props.whatever
,因为它在尝试读取 import
时尚未定义。有办法吗?
补充说明:我正在为该站点使用 Gatsby 静态站点生成器,但这不会真正影响正在发生的事情(至少我认为不会)。
据我所知,上述方法是不可能的,但正如我发现的那样,这是有充分理由的。你必须完全接受 React (Gatsby) 的做事方式,而我上面的方法是试图从 Drupal/WordPress-CMS-build 的角度来做到这一点。
查看我为 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
您会注意到与上述尝试没有太大区别,但请注意 backgroundImage
对象文字中使用的 this.props.nextLocationImgPath.sizes.src
路径。您必须将 backgroundImage
源路径作为道具传递。不要像我一样在组件中尝试这样做。 React 的关注点分离是关于从组件中获取数据,而不是通过 props 提供数据。
那么问题就变成了:如果你必须将路径作为prop传入,那么在页面级别调用组件时如何获取路径?
如果您正在使用 Gatsby
(您应该这样做),则需要使用 GraphQL 来获取优化的图像路径。在我的示例中,我们将在调用 LocationRelated
组件的同一页面上调用 background-image
路径。
专注于手头问题的我页面的简化示例:
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
}
}
}
`
这些 GraphQL 查询提供了我们所需文件的优化路径,现在我们可以通过 this.props.data
将它们发送到我们的 LocationRelated
组件中。
gatsby-image
和 GraphQL 一开始使用起来有点棘手,所以请查看 this nice tutorial by Kyle Gill。它让我比 Gatsby 文档做得更好。
作为参考,这里是我如何在项目中设置我的 gatsby-config.js
以使所有这些插件很好地协同工作(我从项目中的独立 images
目录中提取图像而不是在组件中,所以我需要 gatsby-source-filesystem
与 gatsby-image
、gatsby-transformer-sharp
、gatsby-plugin-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`
}
}
],
};