在反应中使用异步等待从firebase存储中检索图像

Posted

技术标签:

【中文标题】在反应中使用异步等待从firebase存储中检索图像【英文标题】:Using async await to retrieve images from firebase storage in react 【发布时间】:2022-01-12 23:31:55 【问题描述】:

我有一个 useEffect 挂钩,里面有两个函数,第一个 (fetchImages) 获取存储在 firebase 存储中的所有用户图像。 第二个 (loadImages) 等待 fetchImages 并将图像设置为状态数组。问题是图像数组返回为空,除非您转到不同的页面并返回......然后数组中填充了图像 url。 我不确定我的 useEffect 钩子或我的异步等待位置是否有问题,或者其他什么。对 currentUser 的 if 检查是因为 currentUser 在首次加载时返回 null。

const [images, setImages] = useState([]); // All user images from storage
useEffect(() => 
    if (currentUser) 
        const fetchImages = async () => 
            setLoading(true)
            const result = await storage.ref(`images/$currentUser.id`).listAll();
            console.log(result)
            const urlPromises = result.items.map((imageRef) =>
                imageRef.getDownloadURL()
            );
            console.log(urlPromises)
            return Promise.all(urlPromises);
        ;

        const loadImages = async () => 
            const images = await fetchImages();
            setImages(images);
            setLoading(false);
        ;
        loadImages();
    
    console.log(loading)
, []);
console.log(images, image)

currentUser userContext 文件

export const UserContextProvider = ( children ) => 
    const [currentUser, setUser] = useState(null);
    // const [currentUser, setUser] = useState('');
    
    useEffect(() => 
        let unsubscribeFromAuth = null;
        unsubscribeFromAuth = auth.onAuthStateChanged(async userAuth => 
            if (userAuth) 
                const userRef = await createUserProfileDocument(userAuth);

                userRef.onSnapshot(snapShot => 
                    setUser(
                        id: snapShot.id,
                        ...snapShot.data()
                    );
                );
             else 
                setUser(null)
            
        );

        return () => 
            unsubscribeFromAuth();
        ;
    , [])
    // console.log(unsubscribeFromAuth)

    const toggleUser = () => 
        auth.signOut()
            .then(() => 
                window.localStorage.clear();
            )
            .then(() => 
                setUser(null)
            )
            .catch(e => console.log('There was a error:'(e)))
    

【问题讨论】:

“currentUser 是因为 currentUser 在第一次加载时返回 null”,这就是问题所在。您可以创建一个与onAuthStateChanged 一起使用的承诺返回函数,并且仅在使用有效用户解析后才执行此函数。 可能你应该首先修复currentUser,确保当且仅当currentUser被设置时页面才能加载 感谢您对@Alexander Staroselsky 的评论,我一直在用这个把头撞到墙上。我现在尝试实现它 有关基于承诺的方法,请参阅***.com/questions/70075205/… 【参考方案1】:

currentUser 添加到useEffect 挂钩的依赖数组中。当currentUser 状态更新时,您希望副作用是获取相关图像或清除它们。

const [images, setImages] = useState([]); // All user images from storage

useEffect(() => 
  if (currentUser) 
    const fetchImages = async () => 
      const result = await storage.ref(`images/$currentUser.id`).listAll();
      const urlPromises = result.items.map((imageRef) =>
        imageRef.getDownloadURL()
      );
      return Promise.all(urlPromises);
    ;

    const loadImages = async () => 
      setLoading(true);
      try 
        const images = await fetchImages();
        setImages(images);
       catch(error) 
        // handle error, log it, show message, etc...
      
      setLoading(false);
    ;
    loadImages();
   else 
    setImages([]);
  
, [currentUser]);

【讨论】:

以上是关于在反应中使用异步等待从firebase存储中检索图像的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js:从 Firebase 存储中检索数据后如何异步加载模板?

在 useEffect 挂钩中取消所有异步/等待任务以防止反应中的内存泄漏的正确方法是啥?

Firebase 存储异步图像下载随机顺序

等待 firebase 加载,直到显示 View

使用 Angular 7 从 Firebase 存储中检索图像

反应等待异步还是重新渲染?