如何在获取数据之前停止组件渲染?

时间:2017-10-19 08:33:43

标签: javascript reactjs redux react-redux

目前在反应中我必须在componentDidMount生命周期方法中执行函数,其中调用操作创建者可以获取数据。但是,该组件使用数据,具体取决于数据是否存在时响应的确定速度。我怎样才能使组件在数据进入内部之前不进行渲染?

componentDidMount() {
    this.props.getTotalHours()
    this.props.getTrained()
  }

渲染功能:

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

Action Creator在应用程序状态中存储来自请求的返回值:

 export function getTotalHours() {
   const url = `${ROOT_URL}dashboard/hours`
   const request = axios.get(url)
   return {
     type: FETCH_HOURS,
     payload: request
   }
 }

3 个答案:

答案 0 :(得分:3)

使用thenawait控制您的异步操作,并使用this.state控制您的内容是否加载。仅在this.state.loaded === true

之后呈现您的内容
constructor(props) {
  super(props)
  this.state = {
    loaded: false
  }
}

async componentDidMount() {
    await this.props.getTotalHours()
    await this.props.getTrained()
    this.setState({loaded: true})
  }

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

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

编辑:如果您关心API调用的效果,可以与Promise.all并行运行。

async componentDidMount() {
   const hours = this.props.getTotalHours()
   const trained = this.props.getTrained()
   await Promise.all([hours, trained])
   this.setState({loaded: true})
 }

答案 1 :(得分:1)

在构造函数中,声明一个状态,例如,例如

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

然后在render方法中,如果this.state.dataLoaded为false,则返回null:

render () {
  const { dataLoaded } = this.state
  return (
    {
      dataLoaded &&
      <YourComponent />
    }
  )
}

在用于获取数据的方法中,请确保在获取数据时调用this.setState({ dataLoaded: true })

答案 2 :(得分:0)

您无法停止渲染,但可以为渲染内容提供条件。

示例

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 (
        <div className="o-layout--center u-margin-top-large">
            <div className="o-layout__item u-width-1/2@medium u-width-1/4@large">
              <div style={{width: '80%', margin: '0 auto'}}>
                <PieChart data={hours} goal={100} label=' Training Hours Completed'/>
              </div>
            </div>
      )
    }