{React Native} Async\Await not working properly with setSate

喜夏-厌秋 提交于 2020-05-09 06:46:07

问题


Can someone help me understand what I am not doing correctly? Consider this simple code

 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);
       });

I am not understanding why setFunImage(images); gets executed before images.push(result); finishes to push all the results into the array. I thought await would block the remainder of the code below it Basically the concept behind what I am trying to do is to have all my results pushed to images and THEN call setFunImage(images);.

How can I achieve that? Is it even possible?

EDIT

I changed my code in hope to find a solution to this and this is where I got to so far:

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);
     }) 
});

Interestingly enough, when this function executes funImage is populated with 1 image, but then when I refresh it gets populated with the rest of my images that I have in my firebase.

Take a look at this GIF of my running app and the issue with the setState


回答1:


The code doesn't work because your forEach is running async code. Which means it will finish running after you set your images. Here's a fix with some explanations in comments -

// 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);
});


来源:https://stackoverflow.com/questions/61630313/react-native-async-await-not-working-properly-with-setsate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!