reactjshigh-order-component

React component sometimes don't show up


I'm in process of learning React (currently high order component) and I have one problem. In my exercise, component sometimes display data and sometimes don't. My code consist of two Component

DisplayList - component that show data passed by props

GetAndDisplayData - high order component that receive DisplayList component, url of API, and desired parameter (to take from API)

Code:

DisplayList.js

class DisplayList extends React.Component{
    render(){

          return(
                <ul>                     
                  {this.props.data.map((input, i) => <li key={i}>{input}</li>)}                   
                </ul>
                );     
    }
}

GetAndDisplayData.js

const GetAndDisplayData = (DisplayList, urlOfData, parameterToGet) =>
class GetAndDisplayDataClass extends React.Component{

    constructor(props){
        super(props);

       this.state = {
           loading: true,
           urlOfData: urlOfData,
           parameterToGet: parameterToGet,
           data: []
       }
    }

    componentDidMount(){
        this.getData(urlOfData, parameterToGet)
    }

getData(urlOfData,parameterToGet){
    
    fetch(urlOfData) 
    .then(data => data.json())
    .then(jsonData => {
       jsonData.map(input =>           
            this.state.data.push(eval("input."+parameterToGet))            
       );      
    })

    this.setState({loading: false})
    console.log(this.state.data)
}  

render(){
   if(this.state.loading){
       return(<p>Data is loading</p>)
   }else{
       return(
           <div>
               <p>Data loaded</p>
               <DisplayList data={this.state.data} />
           </div>
       );
   }
}
}

And call of HOC

render(){
        const GetData = GetAndDisplayData(DisplayList, "https://restcountries.eu/rest/v1/all", "name" );
        return(
           
            <div>    
              <GetData/>
            </div>

        );      

I suppose that problem is something about asynchronous, beacuse if I use some short list of data everthing is working great, but if I use this API and list of 250 object in list, sometimes data don't show up (and sometimes does). What am I doing wrong?


Solution

  • As you already said, data loading is asynchronous, so you must update loading state variable inside the callback function :

    componentDidMount(){
      this.loadData(urlOfData, parameterToGet)
    }
    
    loadData(urlOfData, parameterToGet){
      fetch(urlOfData) 
      .then(data => data.json())
      .then(jsonData => {
        // I didn't understand how you want to map the data
        const data = jsonData.map(...); 
        console.log(data);
        // you must update the state here
        this.setState({loading: false, data: data});
      });
    }