Skip to content Skip to sidebar Skip to footer

How Do I Stop A Component Rendering Before Data Is Fetched?

Currently in react I have to functions in the componentDidMount lifecycle method in which call action creators to which fetch data. The component uses the data however, depending o

Solution 1:

Control your async actions using then or await and use this.state to control whether or not your content gets loaded. Only render your content after this.state.loaded === true

constructor(props) {
  super(props)
  this.state = {
    loaded: false
  }
}

asynccomponentDidMount() {
    awaitthis.props.getTotalHours()
    awaitthis.props.getTrained()
    this.setState({loaded: true})
  }

content() {
  let hours = parseInt(_.map(this.props.hours, 'hours'));
  let trained = _.map(this.props.trained, 'trained');
  return (
    <divclassName="o-layout--center u-margin-top-large"><divclassName="o-layout__item u-width-1/2@medium u-width-1/4@large"><divstyle={{width: '80%', margin: '0auto'}}><PieChartdata={hours}goal={100}label=' Training Hours Completed'/></div></div>
  )
}

render() {
  return (
  <div>
    {this.state.loaded ? this.content() : null}
  </div>
  )
}

edit: If you care about performance in your API calls, you can run them in parallel with Promise.all.

asynccomponentDidMount() {
   const hours = this.props.getTotalHours()
   const trained = this.props.getTrained()
   awaitPromise.all([hours, trained])
   this.setState({loaded: true})
 }

Solution 2:

In your constructor, declare a state variable to track if data is loaded. For example:

constructor (props) {
  super(props)
  this.state = {
    dataLoaded: false
  }
}

Then in your render method, return null if this.state.dataLoaded is false:

render () {
  const { dataLoaded } = this.statereturn (
    <div>
      {
        dataLoaded &&
        <YourComponent />
      }
    </div>
  )
}

And in the methods you use to fetch data, make sure you call this.setState({ dataLoaded: true }) when data has been fetched

Solution 3:

You can't stop the render but you can give conditions to what to render.

Example

render() {
    if(this.props.hours. length <= 0 || this.props.trained.length <= 0 ) {
      return (<div><span>Loading...</span></div>);
    } else {
      let hours = parseInt(_.map(this.props.hours, 'hours'));
      let trained = _.map(this.props.trained, 'trained');
      return (
        <divclassName="o-layout--center u-margin-top-large"><divclassName="o-layout__item u-width-1/2@medium u-width-1/4@large"><divstyle={{width: '80%', margin: '0auto'}}><PieChartdata={hours}goal={100}label=' Training Hours Completed'/></div></div>
      )
    }

Post a Comment for "How Do I Stop A Component Rendering Before Data Is Fetched?"