Have searched up useEffect
calling conventions, async
and await
usage, but for some reason I still cant get my code to work.
I have a list of image names stored in data.recipeImgs
, and each name uses the formula of data.id + i + ".pdf"
, where i
is an index from 0 to length of data.recipeImgs
. I simply wish to fetch every single image download url from firebase storage, and store those urls in a state variable so later on I can map each url to an img
tag. What am I doing wrong? I keep printing out the value of the state variable imgList
after each .then
, and although I am getting the new image urls, the state variable never changes.
// image slideshow for recipe instructions
const [imgList, setImgList] = React.useState([]);
useEffect(() => {
// function for firebase storage
const getImg = async (i) => {
var storageRef = firebase.storage().ref();
// Create a reference to the file we want to download
var imgRef = storageRef.child(data.id + i + ".pdf");
// Get the download URLs for each image
await imgRef
.getDownloadURL()
.then((url) => {
console.log("got one ", imgList);
// append new image url to state var
setImgList([...imgList, url]);
})
.catch((error) => {
console.log(error);
});
};
// make sure data exists before trying to fetch all the images
// from firebase storage
if (data) {
for (let i = 0; i < data.recipeImgs.length; i++) {
getImg(i);
}
}
}, [data]);
// wait for data to finish loading
if (!data) {
return "Loading...";
}
This is for a personal project, and any help would be appreciated, I'm sure I'm doing something stupid
Edit: added map function relevant code
Here is the code for the myList
mapping:
<ui.Grid container>
<ui.Grid item xs={12}>
{imgList.map((url, ind) => {
<img src={url} alt="Recipe image" key={ind} />;
})}
</ui.Grid>
</ui.Grid>
You should use a functional update (doc)
setImgList((imgList) => ([...imgList, url]));
What was happening here was that the imgList
in the callback's scope was always the initial value []
and you override the state value with the latest url
await imgRef
.getDownloadURL()
.then((url) => {
// here imgList has always the initial value []
setImgList([...imgList, url]);
})