Reactjs 如何等待forEach循环完成

Reactjs 如何等待forEach循环完成,reactjs,react-native,foreach,async-await,fetch,Reactjs,React Native,Foreach,Async Await,Fetch,我在尝试获取数据时遇到问题。不幸的是,当我在控制台上记录结果时,在初始页面加载时,数据是空的。但是,当我重新渲染组件时,我成功地接收到数据 这就是我目前拥有的: function Followers({ urlname, navigation }) { const [followersData, setfollowersData] = useState(null) useEffect(() => { // Fetch Followers d

我在尝试获取数据时遇到问题。不幸的是,当我在控制台上记录结果时,在初始页面加载时,数据是空的。但是,当我重新渲染组件时,我成功地接收到数据

这就是我目前拥有的:

function Followers({
   urlname,
    navigation
}) {
    const [followersData, setfollowersData] = useState(null)

    useEffect(() => {
         // Fetch Followers data
         const dataRef = firestore().collection('usernames')
     
            dataRef.doc(urlname)
            .collection('Following')
            .get()
            .then((docSnapshot) => {
            let items = []

            docSnapshot.forEach(doc => {
                let item = {}

                // Store followers, display name and follows info
                dataRef
                .doc(doc.id)
               .get()
                .then((followerDoc) => {
                    const data = followerDoc.data();
                    item.profileName = doc.id
                    item.displayName = data.userName
                    item.followerCount = data.followers
                    item.followingCount = data.following
                })

                items.push(item)
            })
            setfollowersData(items)
            })

    }, [])

return (
    <>
        {console.log('followersData', followersData)}
    </>
)
}

export default Followers
当组件再次呈现时,我会在控制台日志中收到:

followersData [all my data in 4 different objects gets logged]
使用prev state和set initial state empty数组分别为每个项调用
setfollowersdata()

function Followers({
   urlname,
    navigation
}) {
    const [followersData, setfollowersData] = useState([])

    useEffect(() => {
         // Fetch Followers data
         const dataRef = firestore().collection('usernames')
     
            dataRef.doc(urlname)
            .collection('Following')
            .get()
            .then((docSnapshot) => {

            docSnapshot.forEach(doc => {
                let item = {}

                // Store followers, display name and follows info
                dataRef
                .doc(doc.id)
               .get()
                .then((followerDoc) => {
                    const data = followerDoc.data();
                    item.profileName = doc.id
                    item.displayName = data.userName
                    item.followerCount = data.followers
                    item.followingCount = data.following
                    setfollowersData(prev => [...prev,item])
                })

            })
        })

    }, [])

return (
    <>
        {console.log('followersData', followersData)}
    </>
)
}

export default Followers
函数跟随器({
urlname,
航行
}) {
const[followersData,setfollowersData]=useState([])
useffect(()=>{
//获取追随者数据
const dataRef=firestore().collection('用户名')
dataRef.doc(urlname)
.collection('Following')
.get()
。然后((docSnapshot)=>{
docSnapshot.forEach(doc=>{
让项={}
//存储关注者、显示名称和关注信息
数据参考
.doc(doc.id)
.get()
.然后((followerDoc)=>{
const data=followerDoc.data();
item.profileName=doc.id
item.displayName=data.userName
item.followerCount=data.follower
item.FollowCount=数据.FollowCount
setfollowersData(上一个=>[…上一个,项目])
})
})
})
}, [])
返回(
{console.log('followersData',followersData)}
)
}
导出默认跟随者

William的解决方案很好,但作为一种选择,可以等待所有响应并更新一次状态

const promises = [];

docSnapshot.forEach((doc) => {
  const promise = dataRef
    .doc(doc.id)
    .get()
    .then((followerDoc) => {
      const data = followerDoc.data()

      return {
        profileName: doc.id,
        displayName: data.userName,
        followerCount: data.followers,
        followingCount: data.following,
      }
    });

   promises.push(promise);
})

Promise.all(promises).then(setfollowersData);

非常感谢,这工作得非常完美。不幸的是,我尝试了这一操作并收到了一个错误:可能未处理的承诺拒绝(id:2):TypeError:undefined不是一个函数(靠近“…docSnapshot.map…”),我想出于某种原因,您只能在这里使用forEach方法。另外,我能问一下为什么威廉姆斯的选择可能不那么好吗?谢谢哦,我明白了。这是Firestore的一个特点。它不是数组。只是一个带有forEach方法的对象。我已经更新了密码。非常感谢。这同样有效,但是,初始状态需要是const[followersData,setfollowersData]=useState(),而不是const[followersData,setfollowersData]=useState([]),这比williams的答案更有效吗?我觉得这实际上取决于你的需要,以及你将如何看待这个或那个价值。您可以“显示”一个空数组(不显示任何内容,这是William的建议),或者,如果值为null或未定义,您也可以显示loader。
const promises = [];

docSnapshot.forEach((doc) => {
  const promise = dataRef
    .doc(doc.id)
    .get()
    .then((followerDoc) => {
      const data = followerDoc.data()

      return {
        profileName: doc.id,
        displayName: data.userName,
        followerCount: data.followers,
        followingCount: data.following,
      }
    });

   promises.push(promise);
})

Promise.all(promises).then(setfollowersData);