简体   繁体   中英

I am trying to pull data from firestore and set it to my array using the snapShot method

I am trying to set incoming data from firestore to an array in state. I am using the snapShot method to receive data changing events, and display users and updates but i only seem to receive only one document back.

import React, { Component } from 'react'
import firebase from '../firebase'

export class Display extends Component {
    constructor(){
        super();

        this.state={
            usersArr: []
        }
    }


componentDidMount(){
    const db = firebase.firestore()

    db.collection('users')
    .onSnapshot(snap => {
        let changes = snap.docChanges()
        changes.forEach(change =>{
            this.setState({usersArr: change.doc.data()})
        })
    })
}


When you do this,

changes.forEach(change =>{
   this.setState({usersArr: change.doc.data()})
})

Every time forEach executes, it updates existing usersArr from state and replaces it with latest one. So you end up with only last data in state.

To get rid of this, you can use previous state in setState and concat the new result to existing one.

changes.forEach(change =>{
   this.setState(prevState=>({
      ...prevState,
      usersArr : prevState.usersArr.concat(change.doc.data())
    }), ()=>console.log(this.state.usersArr))
})

You may be getting multiple changes, but when you're looping over them and then set the state based on each individual document:

let changes = snap.docChanges()
changes.forEach(change =>{
    this.setState({usersArr: change.doc.data()})
})

So the first iteration you're setting the state to the first changed document, the second iteration to the second document (overwriting the first), the third iteration to the third document (overwriting the second). So at the end of the loop, you only have the last document left in the state.

If you want to set the data of all changed documents to the state, you'd do something like this:

let docs = []
let changes = snap.docChanges()
changes.forEach(change =>{
    docs.push(change.doc.data())
})
this.setState({usersArr: docs})

The above only adds the changed documents to the state. So initially that will be all documents, but when you later add a single document, the docChanges() will only contain that one document. It is more typical to add all documents to the state, which you do by iterating over snap instead of over snap.docChanges :

let docs = []
snap.forEach(doc =>{
    docs.push(doc.data())
})
this.setState({usersArr: docs})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM