I am working on a project using react where I plug in data from a JSON file into a reducer function to manage the content state. However, at a certain viewport, another image is provided that needs to be displayed instead of the other image. If I am using useReducer, how can I change the image source once a certain viewport is reached? Attached are snippets from my code
Example of JSON data source:
{
"name": "Starry Night",
"year": 1889,
"description": "Although The Starry Night was painted during the day in Van Gogh's ground-floor studio, it would be inaccurate to state that the picture was painted from memory. The view has been identified as the one from his bedroom window, facing east, a view which Van Gogh painted variations of no fewer than twenty-one times, including The Starry Night. \"Through the iron-barred window,\" he wrote to his brother, Theo, around 23 May 1889, \"I can see an enclosed square of wheat ... above which, in the morning, I watch the sun rise in all its glory.\"",
"source": "https://en.wikipedia.org/wiki/The_Starry_Night",
"artist": {
"image": "../assets/starry-night/artist.jpg",
"name": "Vincent Van Gogh"
},
"images": {
"thumbnail": "../assets/starry-night/thumbnail.jpg",
"hero": {
"small": "../assets/starry-night/hero-small.jpg", //This is mobile
"large": "../assets/starry-night/hero-large.jpg" //This is for tablet and up
},
"gallery": "../assets/starry-night/gallery.jpg"
}
},
// Where image is rendered using useState():
<ImageWorks
className="gallery__image"
source={state.image}
alt={`"${state.name}" by ${state.artist}, ${state.year}`}
/>
// How state is managed with useReducer():
const [i, setIndex] = useState(0)
const contentReducer = (state, actions) => {
switch (actions.type) {
case ACTIONS.UPDATE:
return {
...state,
image: data[i].images.hero.small,
name: data[i].name,
artist: data[i].artist.name,
artistImg: data[i].artist.image,
year: data[i].year,
description: data[i].description,
source: data[i].source,
}
default:
return state
}
}
const [state, dispatch] = useReducer(contentReducer, {
image: data[0].images.hero.small,
name: data[0].name,
artist: data[0].artist.name,
artistImg: data[0].artist.image,
year: data[0].year,
description: data[0].description,
source: data[0].source,
})
So for example, I would need to change the image from 'data[0].images.hero.small' to 'data[0].images.hero.large' once my viewport is met.
Thanks for the help!
solved my own issue
easily achieved with this media query package: https://www.npmjs.com/package/react-responsive
read the documentation on how to implement, in my case, this is how I would use it:
const isMobile = useMediaQuery({ query: '(max-width: 375px)' })
const [state, dispatch] = useReducer(contentReducer, {
imageMobile: data[0].images.hero.small, // set below 375px
imageLarge: data[0].images.hero.large, // set above 375px
name: data[0].name,
artist: data[0].artist.name,
artistImg: data[0].artist.image,
year: data[0].year,
description: data[0].description,
source: data[0].source,
})
<ImageWorks
className="gallery__image"
source={isMobile ? state.imageMobile : state.imageLarge} // ternary
alt={`"${state.name}" by ${state.artist}, ${state.year}`}
/>