У меня есть функция, которая позволяет получить изображение из хранилища Firebase:
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;
}
Затем это вызывается внутри компонента React:
import { getImage } from 'API/Storage/getImage';
const EventPage = (props) => {
return (
<div>
<img src = {getImage('image.jpg')}
</div>
);
}
export default EventPage;
Однако изображение не отображается, а вместо этого показывает: <img src = "[object Promise]" alt = "Show Image">
Каков наилучший способ выполнения обещания? Ведение журнала консоли ImageURL
в функции getImage
возвращает URL-адрес, как и ожидалось.
Вам нужно дождаться обещания разрешить. Вы можете получить данные в useEffect
и сохранить значение в useState
.
Вот простой пример:
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;
useEffect
в приведенном выше примере не учитывает случай, когда ваш компонент размонтирован во время получения данных. Реализация, учитывающая это, выглядит так:
useEffect(() => {
let wasUnmounted = false;
getImage('image.jpg').then((image) => {
if (wasUnmounted) return;
setImage(image);
});
return () => {
wasUnmounted = true;
};
}, []);
Обратите внимание, что обратный вызов, предоставленный useEffect
, не является async
. Это потому, что функции async
возвращают обещание. Чтобы иметь возможность определить, что компонент был размонтирован, нам нужно вернуть обратный вызов (он будет вызываться при размонтировании компонента из-за пустого массива, переданного в качестве второго аргумента). Подробнее о useEffect
читайте здесь: https://reactjs.org/docs/hooks-reference.html#useeffect
В
getImage
вместоreturn await ImageURL;
можно просто написатьreturn ImageURL;