I have the following component in a Gatsbyjs project:
styleItem.js
import React from 'react'
import styled from 'styled-components'
import BackgroundImage from 'gatsby-background-image'
import {StaticQuery, graphql } from "gatsby"
import {Col } from 'react-bootstrap'
import '../styles/styles.css'
const StyleItem = (props) => {
return (
<StaticQuery
query={graphql`
query {
street: file(relativePath: { eq: "2.jpg" }) {
childImageSharp {
fluid(quality: 90, maxWidth: 1920) {
...GatsbyImageSharpFluid_withWebp
}
}
}
casual: file(relativePath: { eq: "3.jpg" }) {
childImageSharp {
fluid(quality: 90, maxWidth: 1920) {
...GatsbyImageSharpFluid_withWebp
}
}
}
athletic: file(relativePath: { eq: "3.jpg" }) {
childImageSharp {
fluid(quality: 90, maxWidth: 1920) {
...GatsbyImageSharpFluid_withWebp
}
}
}
}
`}
render={data => { Object.keys(data).map((image, i ) => {
console.log(props.stylesItem[image].name)
console.log(image)
return (
<Col md={4}>
<div class="style-box">
<StyledBackgroundImage
Tag="div"
className="style-box-img"
fluid={data[image].childImageSharp.fluid}
>
</StyledBackgroundImage>
<div class="style-text-box">
<h5 class="h5">{props.stylesItem[image].style}</h5>
<h3 class="h3 style-description">{props.stylesItem[image].name}</h3>
<div class="extra-style-details">
<p class="style-short-desc">{props.stylesItem[image].tagline}</p>
<p>{props.stylesItem[image].text}</p>
<ul class="hashtag-list">
<li class="style-attribut"></li>
</ul>
</div>
</div>
</div>
</Col>
)
})
}
}
/>
)
}
export default StyleItem
const StyledBackgroundImage = styled(BackgroundImage)`
background-size: cover;
background-position: center;
background-repeat: no-repeat;
`
I'm passing in the following props to this component (abc dummy strings for better readability):
stylesItem: {
street: {
style: "// STREET",
name: "THE CANVAS",
tagline: "abc",
text: "abc",
hashtags: [
"abc", "abc", "abc", "abc"
]
},
casual: {
style: "// CASUAL",
name: "THE CLASSIC",
tagline: "abc",
text: "abc",
hashtags: [
"abc", "abc", "abc", "abc", "abc", "abc"
]
},
athletic: {
style: "// ATHLETIC",
name: "THE PERFORMER",
tagline: "abc",
text: "abc",
hashtags: [
"abc", "abc", "abc", "abc", "abc", "abc"
]
}
}
I'm using Gatsby's Staticquery to load in 3 images (street, casual, athletic) and want to render the part in the second return statement 3 times (1 for each image), each time with the background image loading in dynamically as well as the content.
The 2 console.log() statements print out as expected.
console.log(props.stylesItem[image].name)
console.log(image)
THE CANVAS
street
THE CLASSIC
casual
THE PERFORMER
athletic
However nothing gets rendered to the screen and I'm not seeing any errors. What am I doing wrong?
Thanks in advance for your help
Your render prop on StaticQuery
doesn't return anything, and therefore doesn't render anything.
In the StaticQuery
render prop you are mapping over the keys of the queried data, then generating a bunch of JSX successfully. But notice you are not actually doing anything with it because the resulting JSX doesn't get returned.
So the entire StyleItem
component does a bunch of work and then doesn't render anything, because the only thing it renders is StaticQuery
.
const StyleItem = ({ stylesItem }) => {
return (
<StaticQuery
query={graphql`
query {
street: file(relativePath: { eq: "1.png" }) {
childImageSharp {
fluid(quality: 90, maxWidth: 1920) {
...GatsbyImageSharpFluid_withWebp
}
}
}
casual: file(relativePath: { eq: "2.png" }) {
childImageSharp {
fluid(quality: 90, maxWidth: 1920) {
...GatsbyImageSharpFluid_withWebp
}
}
}
athletic: file(relativePath: { eq: "3.png" }) {
childImageSharp {
fluid(quality: 90, maxWidth: 1920) {
...GatsbyImageSharpFluid_withWebp
}
}
}
}
`}
render={data => {
// Make sure to return something here
return Object.keys(data).map(imageTitle => {
const fluidProp = data[imageTitle].childImageSharp.fluid
const imageData = stylesItem[imageTitle]
return (
<>
<StyledBackgroundImage
Tag="div"
className="style-box-img"
fluid={fluidProp}
></StyledBackgroundImage>
<div>
<h5>{imageData.style}</h5>
<h3>{imageData.name}</h3>
<p>{imageData.tagline}</p>
<p>{imageData.text}</p>
</div>
</>
)
})
}}
/>
)
}
Something worth nothing with Arrow functions is that
when the only statement in an arrow function is
return
, we can removereturn
and remove the surrounding curly brackets
(param1, param2, …, paramN) => expression
// equivalent to: => { return expression; }
So the above render prop on StaticQuery
could be further simplified as:
render={data =>
Object.keys(data).map(imageTitle => {...})
}