简体   繁体   中英

Display loader icon while data is loading

I am trying to show loader icon when data loads. But for some reason I am not being able to display this loader icon when I am trying to retrieve data from API.

I have folder structure like this:

  • components
    • dashboard
      • Cards.js
      • Dashboard.js

I have following code in my Cards.js

constructor(props) {
    super(props);
    this.state = this.state = {
        posts: [],
        loading: false
    }
}

componentWillMount() {
    this.loadData();
}

render() {
    let data;
    if(this.state.loading) {
        data = <img data-src={ require('../images/loader.gif') } />
    } else {
        let records = this.fetchResult();

        console.log(records);

        return (
            <div className='row'>
                { records }
            </div>
        )
    }
}

// ==================================================================
loadData() {
    const path = `${url}/jira_jobs.php`;
    axios.get(path)
        .then(res  => {
            this.setState({
                posts: res['data'],
                loading: false
            });
        })
        .catch(err => {
            console.error(err);
        });
}

fetchResult() {
    let records = this.state.posts.map((post) => (
        <div key = { post.id }>
            <h3>{ post.title }</h3>
            <p>{ post.body }</p>
        </div>
    ));

    return records;
}

You aren't setting loading to true anywhere. Try setting loading to true at the beginning of the loadData() method:

loadData() {
    this.setState({loading: true});
    const path = `${url}/jira_jobs.php`;
    axios.get(path)
        .then(res  => {
            this.setState({
                posts: res['data'],
                loading: false
            });
        })
        .catch(err => {
            console.error(err);
        });
}

This works due to the asynchronous nature of the promises you are using.

You don't set your loading property to true anywhere. You should set it to true in the beginning of your loadData function like this:

loadData() {
    this.setState({
       loading: true
    });
    const path = `${url}/jira_jobs.php`;
    axios.get(path)
        .then(res  => {
            this.setState({
                posts: res['data'],
                loading: false
            });
        })
        .catch(err => {
            console.error(err);
        });
}

Also in your render method do this:

render() {
    if(this.state.loading) {
        return <img data-src={ require('../images/loader.gif') } />;
    } else {
        let records = this.fetchResult();

        console.log(records);

        return (
            <div className='row'>
                { records }
            </div>
        )
    }
}

You don't set loading to true inside loadData and you aren't returning the loader from render, Also don't forget to set loading to false when error occurs.

loadData() {
  this.setState({ loading: true });
  const path = `${url}/jira_jobs.php`;
  axios.get(path)
    .then(res => {
      this.setState({
        posts: res['data'],
        loading: false
      });
    })
    .catch(err => {
      this.setState({ loading: false });
      console.error(err);
    });
}

With the ternary operator ? you can include your loader in a much nicer syntax then if else

Also the image source should be src and not data-src

render() {
  return (
    <div className='row'>
      {this.state.loading
        ? <img src={require('../images/loader.gif')} />
        : this.fetchResult()
      }
    </div>
  );
}

try to this code

    loadData() {
const {loading,posts}this.state
    this.setState({!loading});
    const path = `${url}/jira_jobs.php`;
    axios.get(path)
        .then(res  => {
            this.setState({
                posts: res['data'],
                !loading
            });
        })
        .catch(err => {
            console.error(err);
        });
}

tell me if it work or not in commit

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