I have a React project where i get photo URLs from firebase storage (getPhotoArray function) I have the correct urls being console logged when i click the button, but it doesnt show on my page.
I have multiple photos in the firebase storage folder and i am getting the right amount and right photos console logged in the array(in getPhotoArray function)
export const getPhotoArray = async (selectedDonation, setPhotos) => {
const listRef = ref(storage, '/Images/'+selectedDonation.id);
const images = []
listAll(listRef)
.then((res) => {
if (res.items.length > 0) {
res.items.forEach((itemRef) => {
// Get the download URL
getDownloadURL(ref(storage, itemRef.fullPath))
.then((url) => {
images.push(url)
})
.catch((error) => {
});
});
setPhotos(images)
console.log(images)
}else {
toast.info('No Photos Found, Please Try Again Later')
}
}).catch((error) => {
});
}
import React, {useEffect, useMemo, useState} from 'react'
import './donation_information.css'
import {getReceiptURL, getPhotoArray} from '../../API/FirestoreAPI'
export default function DonationInformation({ selectedDonation, selectedDonationSteps }) {
const [Photos, setPhotos] = useState([]);
const getPhotos = () => {
getPhotoArray(selectedDonation, setPhotos)
}
useEffect(() => {
setURL('')
setPhotos([])
}, [selectedDonation]);
return (
<div className='donationInformation'>
<div className='download-photos'>
<button onClick={getPhotos}>Show Photos</button>
{
useMemo(() => {
Photos.map((photo) => {
return <img src="photo" key={photo} alt="" />
})
}, [Photos])
}
</div>
</div>
</div>
)
}
I have tried wrapping the Photos.map with useEffect, thats the only thing i could think of
2
Answers
You need to add curly braces {} to your <img src attribute instead of double quotes as src is set to a variable
photo
. Also set a width and heightYour current code :
return <img src="photo" key={photo} alt="" />
needs to be updated to
return <img src={photo} key={photo} alt="" width="500" height="600"/>
Problem is with this code:
Each
forEach
iteration does not wait forgetDownloadURL
to resolve, so yoursetPhotos(images)
gets called before all URLs are pushed.In order to wait for the URLs to load, you need to use
async/await
:On a side note, sending a state setter to the external method doesn’t feel like the best approach. You’d better return the image URLs from the method and then set that as your state inside the component.