img src 不通过函数加载图像
img src doesn't load image through function
首先,我做了一个沙盒:https://codesandbox.io/s/naughty-almeida-u66mlt?file=/src/App.js
问题是调用函数并返回 url 时请求的图像不显示。
到目前为止我尝试了什么以及结果:
首先我在querySnapshot.forEach
里面添加了getDownloadURL()
并将检索到的 url 推送到路径数组。看起来像
这个:
useEffect(() => {
const q = query(collection(db, "gallery"));
const unsubscribe = onSnapshot(q, (querySnapshot) => {
const path = [];
querySnapshot.forEach((doc) => {
getDownloadURL(ref(storage, doc.data().bild)).then((url) {
path.push(doc.data(), url);
})
});
console.log(path);
setPaths(path);
});
setLoading(false);
return unsubscribe;
}, []);
然后我映射了路径,但图像没有显示。
我创建了另一个 useState
并调用了函数 getURL(src)
querySnapshot.forEach()
里面。在 getURL()
函数中我更新了它
从 getDownloadURL()
检索到 url 的状态。后来我
将状态添加到 src 并且它起作用了。
但我担心的是,当有不止一张图像时它会失败,我
还没有测试过。
我将检索到的 url 形式 getDownloadURL
转换为字符串。像这样
function getURL(src) {...} return String(url)
但这也没有用。
<img />
使用“alt”文本呈现,所以我认为它与 url.
有关
我不太明白这个问题,希望有人能帮我解决。
您可以将组件拆分成小组件。比方说 Gallery 和 GalleryImage。
GalleryImage 将采用 src
和 description
道具。在此组件中声明一个 imageSrc
状态变量。然后您可以在 useEffect 中进行调用(在 dependencies 数组中使用 src
),然后在调用完成时设置 imageSrc
状态。调用 setImageSrc
将触发 re-render.
从 Firestore 加载数据和下载图像 URL 都是异步操作。在对 path.push(doc.data(), url)
的任何调用发生之前,您正在调用 setPaths(path)
。
我推荐 运行 调试器中的代码或添加日志记录来验证这一点,因为这是理解如何处理异步 API 的关键。
解决方案始终相同:任何需要异步加载数据的代码都需要在数据可用时调用的回调中。
所以在你的情况下,最简单的方法是:
onSnapshot(q, (querySnapshot) => {
const path = [];
querySnapshot.forEach((doc) => {
getDownloadURL(ref(storage, doc.data().bild)).then((url) {
path.push(doc.data(), url);
setPaths(path); //
})
});
});
这会在您每次下载时设置路径 URL。
如果您想等到下载完所有文件 URLs 后再设置路径,您可以使用计数器来检查文档数与下载数 URLs,或者您可以使用承诺和 Promise.all
:
onSnapshot(q, (querySnapshot) => {
const promises = querySnapshot.docs.map((doc) => getDownloadURL(ref(storage, doc.data().bild)))
Promise.all(promises).then((urls) {
setPaths(urls);
})
});
首先,我做了一个沙盒:https://codesandbox.io/s/naughty-almeida-u66mlt?file=/src/App.js
问题是调用函数并返回 url 时请求的图像不显示。
到目前为止我尝试了什么以及结果:
首先我在
querySnapshot.forEach
里面添加了getDownloadURL()
并将检索到的 url 推送到路径数组。看起来像 这个:useEffect(() => { const q = query(collection(db, "gallery")); const unsubscribe = onSnapshot(q, (querySnapshot) => { const path = []; querySnapshot.forEach((doc) => { getDownloadURL(ref(storage, doc.data().bild)).then((url) { path.push(doc.data(), url); }) }); console.log(path); setPaths(path); }); setLoading(false); return unsubscribe; }, []);
然后我映射了路径,但图像没有显示。
我创建了另一个
useState
并调用了函数getURL(src)
querySnapshot.forEach()
里面。在getURL()
函数中我更新了它 从getDownloadURL()
检索到 url 的状态。后来我 将状态添加到 src 并且它起作用了。但我担心的是,当有不止一张图像时它会失败,我 还没有测试过。
我将检索到的 url 形式
getDownloadURL
转换为字符串。像这样function getURL(src) {...} return String(url)
但这也没有用。
<img />
使用“alt”文本呈现,所以我认为它与 url.
我不太明白这个问题,希望有人能帮我解决。
您可以将组件拆分成小组件。比方说 Gallery 和 GalleryImage。
GalleryImage 将采用 src
和 description
道具。在此组件中声明一个 imageSrc
状态变量。然后您可以在 useEffect 中进行调用(在 dependencies 数组中使用 src
),然后在调用完成时设置 imageSrc
状态。调用 setImageSrc
将触发 re-render.
从 Firestore 加载数据和下载图像 URL 都是异步操作。在对 path.push(doc.data(), url)
的任何调用发生之前,您正在调用 setPaths(path)
。
我推荐 运行 调试器中的代码或添加日志记录来验证这一点,因为这是理解如何处理异步 API 的关键。
解决方案始终相同:任何需要异步加载数据的代码都需要在数据可用时调用的回调中。
所以在你的情况下,最简单的方法是:
onSnapshot(q, (querySnapshot) => {
const path = [];
querySnapshot.forEach((doc) => {
getDownloadURL(ref(storage, doc.data().bild)).then((url) {
path.push(doc.data(), url);
setPaths(path); //
})
});
});
这会在您每次下载时设置路径 URL。
如果您想等到下载完所有文件 URLs 后再设置路径,您可以使用计数器来检查文档数与下载数 URLs,或者您可以使用承诺和 Promise.all
:
onSnapshot(q, (querySnapshot) => {
const promises = querySnapshot.docs.map((doc) => getDownloadURL(ref(storage, doc.data().bild)))
Promise.all(promises).then((urls) {
setPaths(urls);
})
});