Below I have a SubComponent and a MainComponent. This is meant to be a page that displays an image collection. In the Subcomponent using the onclick()
event you can swap between pictures in that collection. The MainComponent will also display links to other collections, but these are links to the same component itself.
The problem is that when I click the link to go to a new collection, my SubComponent will often use the outdated mainImage
to set the imageList state. It will fetch the correct response (data) however and also currentImage
will still use the correct version of mainPicture
and be set correctly. So in other words only the first image of the “image chooser” will use the outdated mainImage
and be set incorrectly.
SubComponent.js
import React, { useState, useEffect } from 'react'
import my_client
import stockimage
const Subcomponent = ({ mainPicture, my_url, identifier }) => {
const [ imagesList, setImageList ] = useState([])
const baseImageUrl = `${my_url}`
const [ currentImage, setCurrentImage ] = useState(`main/${mainPicture}`)
useEffect(() => {
const fetchList = async () => {
const { data, error } = await my_client
.fetch(`${identifier}`)
if (data) {
setImageList([`main/${mainPicture}`, ...(data.map(obj => `sub/${obj.name}`))])
}
if (error) {
console.log(error)
setImageList([])
}
}
fetchList()
console.log("fetched")
setCurrentImage(`main/${mainPicture}`)
}, [identifier, mainPicture])
return (
<div>
{mainPicture ? <img src={`${baseImageUrl}/${currentImage}`} /> : <img src={stockimage} />}
{ imagesList && imagesList.length > 1 &&
<div>
{ imagesList.map((item, item_index) => (
<div key={item_index}>
<img src={`${baseImageUrl}/${item}`} onClick={() => setCurrentImage(item)}/>
</div>
))}
</div>
}
</div>
)
}
export default SubComponent
MainComponent.js (simplified)
import React, { useState, useEffect, useContext } from 'react'
import SubComponent from './SubComponent'
import Context from './Context'
import my_client
import fetchLinks from './Functions.js'
const MainComponent = () => {
const [ mainPicture, setMainPicture ] = useState(location.state?.paramPicture || null)
const { identifier } = useParams()
const my_url = useContext(Context)
const [ links, setLinks ] = useState(null)
useEffect(() => {
const my_fetch = async () => {
const { data, error } = await my_client
.fetch(`${identifier}/main`)
if (data) {
setMainImage(data.mainImage)
setLinks(data.otherImagesData)
}
if (error) {
console.log(error)
}
}
my_fetch()
if (location.state.paramPicture) {
setMainPicture(location.state.paramPicture)
fetchLinks(setLinks)
} else {
my_fetch()
}
}, [identifier])
return (
<div>
<SubComponent mainPicture={mainPicture} my_url={my_url} identifier={identifier} />
{links.map(item => (<Link to={`/view/${item.link}`} state={{ paramPicture: item.picture }}>))}
</div>
)
}
export default MainComponent