How to wait for fetch to complete before rendering page in React.js

Tomas Engquist picture Tomas Engquist · Mar 5, 2020 · Viewed 10.9k times · Source

In this React component, I'm trying to fetch data from the GIPHY API and render it in another component. The fetch is working correctly, but this.state.gifs.map returns an error because it runs before the fetch is complete and the state is set. I have tried using Hooks with async/await but that did not seem to work either. How can I create my gifArray after the state is set so I'm not trying to run .map on an empty array.

import React, {Component} from 'react'
import GifCard from './gifCard.js'
import './App.css'

export default class GifContainer extends Component{

  state = {
    gifs: []
  }

  componentDidMount(){
    fetch('http://api.giphy.com/v1/gifs/search?q=ryan+gosling&api_key=KnzVMdxReB873Hngy23QGKAJh6WtUnmz&limit=5')
    .then(res => res.json())
    .then(gifs => {
      this.setState({gifs})
    })
  }


  render(){
    const gifArray = this.state.gifs.map((gif) => {
      return <GifCard key={gif.name} gif={gif}/>
    })
    return(
      <div>
        <h1 id="heading">Gif Search</h1>
        <div id='gifContainer'>
          {gifArray}
        </div>
      </div>

    )}

}

Answer

boosted_duck picture boosted_duck · Mar 5, 2020

You have to check first if gifs array is not empty. When the setState is done, render will trigger again, and this time there will be gifs to map.

    let gifArray = '';

    if (this.state.gifs.length > 0) {
        gifArray = this.state.gifs.map((gif) => {
          return <GifCard key={gif.name} gif={gif}/>
        })
    }