将所有数据推送到数组后设置状态

Posted

技术标签:

【中文标题】将所有数据推送到数组后设置状态【英文标题】:Set state once all data is pushed to array 【发布时间】:2018-05-10 21:19:19 【问题描述】:

我正在尝试使用 Firebase Firestore 在 React 中制作“facebook 类型的新闻源”。在 componentDidMount 中,我首先获取好友列表,每个好友我将获取他们的活动,我将其推送到一个空数组和 sort() + reverse() id,它们是时间戳。这样,最新的活动将在数组中排在第一位。一旦 ALL 项目被推送到数组,我想用数组设置状态。这是我拥有的代码:

import React,  Component  from 'react'
import  db, firebaseAuth  from '../../helpers/base'
import Activities from './Activities'

export default class ActivityList extends Component 
  state = 
    activityKeys: [],
  

  componentDidMount()
    const uid = firebaseAuth().currentUser.uid
    var activityKeys = []

    db.doc(`users/$uid/social/friends`).get().then( (doc) =>       
      //GET ALL THE FRIENDS
      const friends = doc.data() //OBJECT OF friendOneId: "friendOneId", friendTwoId: "friendTwoId"

      //LOOP THROUGH FRIENDS AND GET ACTIVITY     
      Object.keys(friends).forEach( friend =>           
        db.collection("activity").where("user", "==", friend).get().then((querySnapshot) => 
          querySnapshot.forEach( (doc) => 

          const activity = doc.id
          activityKeys.push(activity)
          activityKeys.sort().reverse()                   
          )                      
        )         
      ) 
    )    
    console.log('activityKeys: ', activityKeys)
    this.setState( activityKeys )                               
  

 render () 
   return (
     <div>
       <h5>Activity List</h5>
       <Activities activityKeys=this.state.activityKeys />        
     </div>
    )
  

问题是数组设置不正确,或者它可能是在所有项目被推送之前设置的。这是我得到的日志:

看起来它已加载,但括号之间为空。如果我 console.log This.state.activity 我得到相同的结果。有人可以告诉我如何解决这个问题吗?一旦所有活动都被推送到空数组中,我该如何设置状态?

【问题讨论】:

【参考方案1】:

当您调用 API 时,您会收到一个 Promise,但您在调用完成之前设置了 this.setState( activityKeys )。换句话说,您必须在收到数据后链接另一个.then(),您将在其中调用this.setState( activityKeys )。有点困难的是,在使用 forEach 进行迭代时,您创建了许多 Promise,并且您需要等待每个 Promise 完成。您可以将它们全部保存到列表中,并使用Promise.all 等待它们完成并从之前的.then 返回。阅读有关承诺的更多信息:https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Global_Objects/Promise

【讨论】:

以上是关于将所有数据推送到数组后设置状态的主要内容,如果未能解决你的问题,请参考以下文章

将复选框值推送到状态 onChange 的数组

如何将状态推送到包含特定项目的数组?

将数据从多个输入推送到状态数组

如何使用ajax将数据推送到数组

反应表单,提交对象,然后将其推送到数组

将表单数据推送到对象数组