简体   繁体   中英

Render React component using Firestore data

I'm trying to render my Guild component with data from Firestore. I put the data from Firestore into my state as an array, then when I call the component and try to render it, nothing shows. I want to believe I'm doing something very wrong here (haven't been working with React for very long), but I'm not getting any errors or warnings, so I'm not sure exactly what's happening.

Guilds.js

<Col>
    <Card>
      <CardBody>
        <CardTitle className={this.props.guildFaction}>{this.props.guildName}</CardTitle>
        <CardSubtitle>{this.props.guildServer}</CardSubtitle>
        <CardText>{this.props.guildDesc}</CardText>
      </CardBody>
    </Card>
  </Col>

Render function

renderCards() {
var guildComp = this.state.guilds.map(guild => {
  console.log(guild)
  return <Guilds
          key={guild.id}
          guildFaction={guild.guildFaction} 
          guildServer={guild.guildServer}
          guildName={guild.guildName} 
          guildDesc={guild.guildDesc} />
 })
return <CardDeck>{guildComp}</CardDeck>
}

Fetching Firestore Data

guildInfo() {
Fire.firestore().collection('guilds')
  .get().then(snapshot => {
    snapshot.forEach(doc => {
      this.setState({
        guilds: [{
          id: doc.id,
          guildDesc: doc.data().guildDesc,
          guildFaction: doc.data().guildFaction,
          guildName: doc.data().guildName,
          guildRegion: doc.data().guildRegion,
          guildServer: doc.data().guildServer
        }]
      })
      console.log(doc.data().guildName)
    })
  })
}

UPDATE: solved, fix is in the render function.

好吧,您使用状态“行会”,但更新状态“职位”,或者我错过了什么?

I see few things here:

  1. your component is Guild.js , but you are rendering <Guilds />
  2. You are setting state to posts , but using this.state.guilds to render the components
  3. You are overriding that piece of state each time to the last object in the snapshot, with the way you are mapping the Firestore data
  4. you are setting the ids in the list wrong using doc.id instead of doc.data().id
  5. You aren't mapping guilds to render. guilds is an array of guild objects, so you should do something like guilds.map(guild => { return <Guild /> }

These are few things to fix, and then try to console.log(this.state.guilds) before rendering and see if you get the right data

I think your issue is that because setState is async, by the time it actually sets the state doc is no longer defined. Try creating the array first, then call setState outside of the loop ie:

guildInfo() {
Fire.firestore().collection('guilds')
  .get().then(snapshot => {
     let guilds = []
     snapshot.forEach(doc => {
       guilds.push({
          id: doc.id,
          guildDesc: doc.data().guildDesc,
          guildFaction: doc.data().guildFaction,
          guildName: doc.data().guildName,
          guildRegion: doc.data().guildRegion,
          guildServer: doc.data().guildServer
       });
     })
     this.setState({guilds});
  })
}

Try to use a map function, and in the callback function of the setState, try to console log your state after the update:

guildInfo() {
  Fire.firestore().collection('guilds')
    .get()
    .then(snapshot => {
       const guilds = snapshot.map(doc => {
         return {
            id: doc.id,
            guildDesc: doc.data().guildDesc,
            guildFaction: doc.data().guildFaction,
            guildName: doc.data().guildName,
            guildRegion: doc.data().guildRegion,
            guildServer: doc.data().guildServer
         };
       this.setState({guilds}, () => console.log(this.state))
      })
    })     
  })
}

If in the console log there's a little [i] symbol near your state, it means that the state is not ready, and therefore it's am async issue. Replacing the forEach with the map function may already help though.

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