Vince Gonzales
Vince Gonzales

Reputation: 985

React Native - How to hide splash screen when all components have been been rendered inside it?

I have a function which fetches data from firebase, SplashScreen.hide() is called when fetching is done and states are set. The problem is, when SplashScreen.hide() is called, the components are still loading for 1 - 2 seconds before they appear, is there a better way of ensuring that the components are already rendered? The items being rendered are dependent on the state cardComponents, which when set will render the cards.

P.S. I'm using react-native-splash-screen

fetchCards = () => {
    let cardRef = firebase.firestore().collection('tblcard')
    let itemRef = firebase.firestore().collection('tblitem')
    let cards = []
    let items = []
    let cardComponents = []
    let today = new Date()
    today.setHours(0, 0, 0, 0)

    cardRef.where('date', '=', today).get().then(function(cardSnapshot) {
      cardSnapshot.forEach(function(doc) {
        cards[doc.id] = doc.data()
      })

      itemRef.get().then(function(itemSnapshot) {
        itemSnapshot.forEach(function(doc) {
          items[doc.id] = doc.data()
        })

        cards.forEach(function(card, index) {
          let id = index
          let item1 = items[card.item1]
          let item2 = items[card.item2]
          let question = card.question.replace('?', ',') + '\n' + item1.item_name + ' o ' + item2.item_name + '?'

          cardComponents.push({id: id, image1: item1.image_url, image2: item2.image_url, question: question})
        })

        this.setState({cardComponents: cardComponents})
        this.setState({cards: cards})
        this.setState({items: items})

        SplashScreen.hide()
      }.bind(this))
    }.bind(this))
}

render () {
  {this.state.cardComponents}
}

Upvotes: 1

Views: 3903

Answers (1)

patngo
patngo

Reputation: 687

This is because calling setState is asynchronous by nature. So when SplashScreen.hide() after setting your state, your state has not been properly updated yet. You have 2 options:

Use the lifecycle method componentDidUpdate to detect that your state has been updated:

  componentDidUpdate(prevProps, prevState) {
    if (prevState.cardComponents !== this.state.cardComponents) {
      SplashScreen.hide();
    }
  }

Use the callback offered in the setState method:

this.setState({cardComponents: cardComponents}, () => { SplashScreen.hide(); })

Upvotes: 4

Related Questions