I have a function which goes off to retrieve an image from Firebase Storage:
import {
getStorage,
ref,
getDownloadURL
} from 'firebase/storage';
const storage = getStorage();
export async function getImage(location) {
const ImageURL = await getDownloadURL(ref(storage, location));
return await ImageURL;
}
This is then called within a React component:
import { getImage } from 'API/Storage/getImage';
const EventPage = (props) => {
return (
<div>
<img src={getImage('image.jpg')}
</div>
);
}
export default EventPage;
However the image doesn't display and instead shows: <img src="[object Promise]" alt="Show Image">
What's the best way of resolving the promise? Console logging ImageURL
within the getImage
function returns the URL as expected.
CodePudding user response:
You need to wait for the promise to resolve. You can fetch the data in a useEffect
and store the value in a useState
.
Here's a basic example:
import { getImage } from 'API/Storage/getImage';
const EventPage = (props) => {
const [image, setImage] = useState();
useEffect(async () => {
const image = await getImage('image.jpg');
setImage(image);
}, []);
return (
<div>
{image ? <img src={image} /> : "Loading image"}
</div>
);
}
export default EventPage;
The useEffect
in the above example doesn't account for the case when your component is unmounted while still fetching the data. An implementation that accounts for that looks like so:
useEffect(() => {
let wasUnmounted = false;
getImage('image.jpg').then((image) => {
if (wasUnmounted) return;
setImage(image);
});
return () => {
wasUnmounted = true;
};
}, []);
Notice that the callback provided to useEffect
isn't async
. That's because async
functions return a promise. To be able to detect that the component was unmounted we need to return a callback (it will be called when the component is unmounted, because of the empty array passed as a second argument). Please read more about useEffect
here: https://reactjs.org/docs/hooks-reference.html#useeffect