我正在尝试从 firebase 存储中提取下载链接列表以显示在我的 React/nextjs 组件中
P粉481035232
P粉481035232 2023-09-15 18:34:49
0
1
768

当尝试拉取数组时,数据始终为空。有人知道我哪里出错了吗? 我检查了控制台,据我所知,有一个对 firebase 存储的引用,但没有数据。但我的存储中有 4 个文档应该输出 URL 链接。 这是我的组件

import React, { useState, useEffect } from 'react';

// i'm initializing firebase with firebase.initializeApp(firebaseConfig)
import { projectStorage } from '@/firebaseConfig'; 
 // projectStorage is =         firebase.storage();


const PDFViewer = () => {
  const [pdfUrls, setPdfUrls] = useState();

  useEffect(()=>{
   const storageRef = projectStorage.ref();
   const pdfRef = storageRef.child('myfirebaselocationpath/uploadeddocs/'); 
   const urls = [];
   pdfRef.listAll().then((result) => {
    result.items.forEach((itemRef) => {
    itemRef.getDownloadURL().then((url) => {
      urls.push(url);
    });
  });
  setPdfUrls(urls);
}).catch((error) => {
  console.error('Error retrieving PDF files:', error);
});
},[])
console.log(pdfUrls)
/*  console.log( pdfUrls.map((url) => {
return url
 })
) */
return (
<div>
  <h1>PDF Viewer</h1>
  {pdfUrls.map((url) => (
    <iframe key={url} src={url} width="100%" height="600px" />
  ))}
</div>
 );
};

export default PDFViewer;`

上面的组件是我尝试过的,并期望映射链接列表,但没有显示任何数据。并且 pdfUrls 始终为空。

P粉481035232
P粉481035232

全部回复(1)
P粉976488015

问题出在这里:

pdfRef.listAll().then((result) => {
  result.items.forEach((itemRef) => {
  itemRef.getDownloadURL().then((url) => {
    urls.push(url);
  });
});
setPdfUrls(urls);

listAllgetDownloadURL 都是异步操作,可能需要一些时间才能完成。主代码不会阻塞整个脚本,而是在操作发生时继续执行 - 然后当数据(文件列表或下载 URL)可用时执行回调块。

这意味着您的 setPdfUrls(urls); 在任何 urls.push(url); 运行之前运行,并且这会设置一个空列表。我建议在调试器中检查这一点,或者添加一些日志记录。


解决该问题的最简单方法是将 setPdfUrls(urls); 移至内部回调:

pdfRef.listAll().then((result) => {
  result.items.forEach((itemRef) => {
  itemRef.getDownloadURL().then((url) => {
    urls.push(url);
    setPdfUrls(urls);
  });
});

现在它会在确定每个下载 URL 后调用。这会执行多次更新,因此可能会导致 UI 中出现一些闪烁,但数据现在应该会显示。


在等待一切完成的同时只调用一次 setPdfUrls(urls); 需要做更多的工作。最简单的方法可能是将整个 useEffect 处理程序标记为 async 并在其中使用 await

useEffect(() => async {
  const storageRef = projectStorage.ref();
  const pdfRef = storageRef.child('myfirebaselocationpath/uploadeddocs/');
  const urls = [];
  const result = await pdfRef.listAll();
  for (const itemRef of result.items) {
    const url = await itemRef.getDownloadURL();
    urls.push(url);
  }
  setPdfUrls(urls);
}, [])

所以这段代码:

  • 使用 await 确保异步操作在调用 setPdfUrls 之前完成。
  • 使用 for...of 循环来确保我们可以在该循环内使用 await
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板