Реагировать на собственные данные, которые не отображаются после установки - PullRequest
0 голосов
/ 15 января 2019

Итак, я работал с firebase в качестве бэкэнда в своем собственном приложении реакции, я пытался извлечь данные таким образом, но у меня ничего не отображается, у меня есть индикатор активности, который гаснет, но я получаю, что массив данных пустой на экране приложения, и когда я делаю console.log, я могу видеть данные в консоли, но на экране приложения ничего не показывается, пожалуйста, помогите мне, это были дни, когда я борюсь.

export default class Leaderboard extends React.Component{


constructor(props){
    super(props)
    this.state = {
        loading : true,
        data : []
    }
}

componentDidMount(){
    firebase.firestore().collection('rankings').get()
        .then(res => {
            let rankArray = []
            res.forEach(document => {
                rankArray.push(document.data())
            })
            return rankArray;
        }).then(res =>{
            let data = []
            res.forEach(item =>{
                firebase.firestore().doc(item.idUser.path)                    
                .get()
                    .then(doc =>{
                        let dataItem = {}
                        dataItem.id = doc.ref.path
                        dataItem.name = doc.data().fullname
                        dataItem.points = doc.data().points
                        dataItem.lc = 'Oran'
                        data.push(dataItem)
                        dataItem = {}

            })
        })
        return data;
    }).then(res =>this.setState({
        loading : false,
        data : res
    })  ).catch(err => console.log(err))


}


render(){

if(this.state.loading){
        return(
        <View style = {styles.container}>
            <ActivityIndicator size= 'large'></ActivityIndicator>
        </View>
        )
}else{
    console.log(this.state.data)
    return(
        <View>
            <Text>{this.state.data.length}</Text>
            <FlatList
                data={this.state.data}
                 renderItem={({item}) => <Text>{item.fullname}</Text>}
            />

        </View>
    )

}

} }

1 Ответ

0 голосов
/ 15 января 2019

Причина, по которой это не работает должным образом, заключается в том, что вы пытаетесь выполнить асинхронный вызов функции на каждую итерацию массива res внутри обратного вызова forEach():

 // This is asynchronous
 firebase.firestore().doc(item.idUser.path).get().then(doc =>{ ... })

Подумайте о пересмотре кода, чтобы вместо него использовать метод Promise.all(). Это обеспечит выполнение каждого асинхронного для отдельных документов для каждого элемента в массиве res до вызова setState() в последующем обработчике .then():

.then(res => {
        let rankArray = []
        res.forEach(document => {
            rankArray.push(document.data())
        })
        return rankArray;
})
.then(res => {

  // Use promise all to resolve each aync request, per item in the 
  // res array
  return Promise.all(res.map(item => {

    // Return promise from .get().then(..) for this item of res array.
    return firebase.firestore()
    .doc(item.idUser.path)
    .get()
    .then(doc => {

      let dataItem = {}
      dataItem.id = doc.ref.path
      dataItem.name = doc.data().fullname
      dataItem.points = doc.data().points
      dataItem.lc = 'Oran'

      // Return resolve dataItem to array that is relayed to next .then()
      // handler (ie where you call this.setState())
      return dataItem
    })
  }));
})
.then(res =>this.setState({
    loading : false,
    data : res
}))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...