{React Native} Async\Await 无法与 setSate 正常工作

Ill*_*lIl 2 async-await firebase reactjs react-native google-cloud-firestore

有人可以帮助我理解我没有做正确的事情吗?考虑这个简单的代码

 var images = []; 
 const [funImage, setFunImage] = useState([]);


//Some function that does this below
firebase.firestore().collection('PostedFunActivities').where("location", "==" , place).get().then((querySnapshot) =>{
        querySnapshot.forEach(async(doc) =>{ 
            const ref = firebase.storage().ref('images/'+ doc.data().image)
            const result = await ref.getDownloadURL();
            images.push(result);                                                                   
           })
           setFunImage(images);
       });
Run Code Online (Sandbox Code Playgroud)

我不明白为什么在完成setFunImage(images);之前执行images.push(result);将所有结果推入数组。我认为await会阻止它下面的其余代码基本上我想做的事情背后的概念是将我的所有结果推送到images然后调用setFunImage(images);.

我怎样才能做到这一点?有可能吗?

编辑

我更改了代码,希望找到解决方案,这就是我到目前为止所达到的位置:

firebase.firestore().collection('PostedFunActivities').where("location", "==" , place).get().then((querySnapshot) => {
   querySnapshot.forEach(async(doc) => {
     const ref = firebase.storage().ref('images/' + doc.data().image)
     const result = await ref.getDownloadURL();
     images.push(result);
     setFunImage(...funImage,images);
     }) 
});
Run Code Online (Sandbox Code Playgroud)

有趣的是,当这个函数执行时,funImage会填充 1 个图像,但是当我刷新时,它会填充 Firebase 中的其余图像。

看看我正在运行的应用程序的 GIF 以及 setState 的问题

Mot*_*Azu 5

该代码不起作用,因为您的 forEach 正在运行异步代码。这意味着它将在您设置图像后完成运行。这是评论中的一些解释的修复 -

// No need for images array outside
const [funImage, setFunImage] = useState([]);

...

firebase.firestore().collection('PostedFunActivities').where("location", "==" , place).get().then(async (querySnapshot) =>{
    // instead of foreach, using map to aggregate the created promises into one array
    // Promise.all takes an array of promises and resolves after all of them completed running
    // returns an array with the promise results
    const images = await Promise.all(querySnapshot.map(async(doc) =>{ 
        const ref = firebase.storage().ref('images/'+ doc.data().image)
        const result = await ref.getDownloadURL();
        return result;                                         
    }));
    setFunImage(images);
});
Run Code Online (Sandbox Code Playgroud)

  • 您应该尝试将“querySnapshot.map”更改为“querySnapshot.docs.map”,因为“querySnapshot”不是您可能期望的数组:https://googleapis.dev/nodejs/firestore/latest/QuerySnapshot.html (2认同)