在Firebase查询填充数组后,如何确保调用setState?

时间:2016-09-13 04:41:11

标签: javascript firebase react-native promise firebase-realtime-database

我是Firebase的新手,并将其与React Native一起使用。我正在尝试使用Firebase中的数据填充ListView。我看到我现在可以在Firebase中使用Promise,但是,似乎我不能将它们与.on()一起使用,而只能与.once一起使用。因为我需要听取更改,所以我需要使用.on()

现在,当我想确保在从Firebase检索数据之后(并且仅在之后)设置状态时,我现在面临挑战。我的代码如下:

listen() {
    var self = this
    var currentUserID = firebase.auth().currentUser.uid
    var postList = firebase.database().ref('/users/'+currentUserID+'/postKeys')
    postList.on('value', function(snapshot) {
      var posts = []
      snapshot.forEach((child)=> {
        var postID = child.val().postID
        var postRef = firebase.database().ref('posts/'+postID)
        postRef.orderByChild('sortedDateInMilliseconds').on('value', function(postSnap) {
          posts.push(postSnap.val())          
        })

      })
      self.setState({
        postCount:posts.length,
        dataSource:self.state.dataSource.cloneWithRows(posts)
      })
    })
  }

结果是我最初得到一个空视图,因为在查询填充posts数组之前调用了render()。有谁知道如何确保在查询填充数组后调用self.setState({})

非常感谢你的帮助。

2 个答案:

答案 0 :(得分:1)

我不完全确定用空数组调用你的意思。我可以想象的唯一原因是,如果您最初在该位置尚无数据时被调用。如果这是原因,您可以使用snapshot.exists()检测到它:

listen() {
    var self = this
    var currentUserID = firebase.auth().currentUser.uid
    var postList = firebase.database().ref('/users/'+currentUserID+'/postKeys')
    postList.on('value', function(snapshot) {
      if (snapshot.exists()) {
        var posts = []
        snapshot.forEach((child)=> {
          var postID = child.val().postID
          var postRef = firebase.database().ref('posts/'+postID)
          postRef.orderByChild('sortedDateInMilliseconds').on('value', function(postSnap) {
            posts.push(postSnap.val())          
          })

        })
        self.setState({
          postCount:posts.length,
          dataSource:self.state.dataSource.cloneWithRows(posts)
        })
      }
    })
  }

如果这不能解决问题,你可以设置一个再现它的jsbin吗?

答案 1 :(得分:-2)

您可以将setTimeout功能用作

setTimeOut(try,3000); 
function try(){
self.setState({
        postCount:posts.length,
        dataSource:self.state.dataSource.cloneWithRows(posts)
      });
}

如果不将3000更改为5000

,将在查询后调用self.setState({})