How can I wait until all images are loaded in React.JS?
The problem is that I do some calculations (image processing) using those images and the results are different between multiple refreshes of the browser because at certain times the calculations start before the images are 100% loaded. Is there a way to wait until 100% of all images are loaded?
I've tried something like this:
const [imagesLoaded, setImagesLoaded] = useState(false);
{images.map((image, index) => {
return <ShowImage source={image} index={index 1} key={index} onl oad={() => setImagesLoaded(index)} />
})}
const ShowImage: React.FC<{source:string, index: number, onl oad: () => void}> = ({source, index, onl oad}) => {
return (
<img src={source} width="640" height="480" id={'image' index} alt={'image' index} onl oad={onLoad}/>
)
}
And the 'checker':
useEffect(() => {
if(imagesLoaded === 5) {
... do something
}
}, [imagesLoaded]);
But the problem is that this is working only for the first page render, if I refresh is not working, but I refresh one more time is working again and sometimes needs more refreshes, what's the problem?
CodePudding user response:
You could refactor your ShowImage
component to only set imagesLoaded
when the last image source URL is loaded.
function ShowImages({ urls, setImagesLoaded }) {
const onl oad = (index) => {
if (index === urls.length - 1) {
setImagesLoaded(true)
}
};
return (
<>
{urls.map((url, index) => (
<img src={url} onl oad={() => onl oad(index)} key={url} />
))}
</>
);
}
export default ShowImages;
And use the component something like this
const [imagesLoaded, setImagesLoaded] = useState(false);
...
useEffect(() => {
if(imagesLoaded) {
... do something
}
}, [imagesLoaded]);
...
<ShowImages urls={images} setImagesLoaded={setImagesLoaded}/>
CodePudding user response:
Your images might not load in the intended order. If your 4th image loads after the 5th one, then the value of imagesLoaded
will be 4
at the end.
To prevent that, I would increment the value one at a time, so when all five images are loaded the value will be 5.
onLoad={() => setImagesLoaded(v => v 1)}