Reactjs:如何在安装组件之前获取要加载的数据?

时间:2015-10-12 22:24:54

标签: javascript reactjs

发生了一些奇怪的事情,我一直在阅读React文档,他们谈论生命周期以及如何在渲染组件之前做一些事情。我正在尝试,但我尝试的一切都失败了,总是组件首先进行渲染,然后调用componenWillMount,.. diMount等等。在调用这些函数之后,渲染再次发生。

我需要首先加载数据以填充状态,因为我不希望初始状态为null,我希望它与初始渲染后的数据一样。

我正在使用Flux和Alt,这是

动作

@createActions(flux)
class GetDealersActions {

  constructor () {
    this.generateActions('dealerDataSuccess', 'dealerDataFail');
  }

  getDealers (data) {
    const that = this;
    that.dispatch();
    axios.get(`${API_ENDPOINT}/get-dealers/get-dealers`)
      .then(function success (response) {
        console.log('success GetDealersActions');
        that.actions.dealerDataSuccess({...response.data});
      })
  }
}

然后商店

@createStore(flux)
class GetDealersStore {

  constructor () {
    this.state = {
      dealerData : null,
    };
  }

  @bind(GetDealersActions.dealerDataSuccess)
  dealerDataSuccess (data) {
    this.setState({
      dealerData : data,
    });
  }

}

组件

@connectToStores
export default class Dealers extends Component {

  static propTypes = {
    title : React.PropTypes.func,
  }

  static contextTypes = {
    router : React.PropTypes.func,
  }

  constructor (props) {
    super(props);
    this.state = {
      modal : false,
      dealerData : this.props.dealerData,
    }
  }

  componentWillMount () {
    GetDealersActions.getDealers();
    this.setState({
      dealerData : this.props.dealerData.dealersData,
    })
  }

  static getStores () {
    return [ GetDealersStore ];
  }

  static getPropsFromStores () {
    return {
      ...GetDealersStore.getState(),
    }
  }

  render () {

    return (<div>
          <div style={Styles.mainCont}>
            {!!this.props.dealerData ?
              this.props.dealerData.dealersData.map((dealer) => {
                return (<div>HERE I AM RENDERING WHAT I NEED</div>);
              }) : <p>Loading . . .</p>
            }
          </div>
      </div>
    );
  }

}

正如您在组件部分中看到的那样,我有这个

  constructor (props) {
    super(props);
    this.state = {
      modal : false,
      dealerData : this.props.dealerData,
    }
  }

  componentWillMount () {
    GetDealersActions.getDealers();
    this.setState({
      dealerData : this.props.dealerData.dealersData,
    })
  }

告诉我dealerData is undefinedcan not read property of null

我需要的只是知道一种技术,我可以在初始渲染发生之前获取数据。所以我可以填写state并开始处理这些数据。

2 个答案:

答案 0 :(得分:4)

React确保componentWillMount中的状态分配将在第一次渲染之前进行。正如你在评论中所说:

  

在初始渲染发生之前,在客户端和服务器上调用一次。如果在此方法中调用setState,则render()将看到更新的状态,并且只会在状态更改时执行一次。

但是,请求的异步操作不会立即更新您的商店。调用GetDealersActions.getDealers();将发出使用新内容更新商店的情况,但响应将仅在事件队列中稍后到达。这意味着this.props.dealersData在函数期间不会更改,setState将尝试读取未定义属性的属性“dealersData”。无论如何,在第一次渲染时无法看到请求的内容。

我的建议与similar question中的建议相同。防止组件呈现该内容,直到它变得可用为止,正如您所做的那样,在程序中是一件合适的事情。或者,在“dealersData”尚未到达的情况下渲染装载程序。

要解决您的特定问题,请从setState删除componentWillMount。如果您的父组件正在正确地监听更改并将它们传播到子项的道具,那么所有这些都应该可以正常工作。

componentWillMount () {
  GetDealersActions.getDealers();
}

答案 1 :(得分:1)

我用来从服务器接收数据并显示它的最佳答案

constructor(props){
        super(props);
        this.state = {
            items2 : [{}],
            isLoading: true
        }

    }

componentWillMount (){
 axios({
            method: 'get',
            responseType: 'json',
            url: '....',

        })
            .then(response => {
                self.setState({
                    items2: response ,
                    isLoading: false
                });
                console.log("Asmaa Almadhoun *** : " + self.state.items2);
            })
            .catch(error => {
                console.log("Error *** : " + error);
            });
    })}

 render() {
   return(
       { this.state.isLoading &&
                    <i className="fa fa-spinner fa-spin"></i>

                }
                { !this.state.isLoading &&
            //external component passing Server data to its classes
                     <TestDynamic  items={this.state.items2}/> 
                }
         ) }