无需等待React JS中的API数据即可进行渲染

时间:2016-05-26 09:26:03

标签: javascript ajax reactjs flux reactjs-flux

我是ReactJS的新手,我正在创建单一注册页面App,其中下拉数据来自API,但当我尝试获取数据时,显示错误。

我的示例代码如下:

AppApi.js:

var AppActions =require('../actions/AppActions');
var request = require('superagent');

var Data= {};
module.exports ={
        request.get('*http://api.randomuser.me/*')
      .set('Accept', 'application/json')
      .end(function(err, response) {
        if (err) return console.error(err);
           Data.details= response.text;
        AppActions.receiveData(Data.details);


      });
}

我的行动是:

var AppDispatcher = require('../dispatcher/AppDispatcher');
var AppConstants = require('../constants/AppConstants');
var AppActions = {
    receiveData: function(data){
      AppDispatcher.handleViewAction({
          actionType: AppConstants.RECEIVE_DATA,
          data: data
      })
  }
 }
module.exports= AppActions;

我的ConstantFile是:

module.exports ={
    RECEIVE_GENDERS: 'RECEIVE_GENDERS'
}

Dispatcher是:

    var Dispatcher = require('flux').Dispatcher;
    var assign = require('object-assign');
    var AppDispatcher= assign( new Dispatcher(), {
        handleViewAction :function(action){
            var payload ={
                source: 'VIEW_ACTION',
                action: action
            }
            this.dispatch(payload);
        }
    });
   module.exports =AppDispatcher;

在我的商店中:

 var AppDispatcher = require('../dispatcher/AppDispatcher');
    var AppConstants = require('../constants/AppConstants');
    var EventEmitter =require('events').EventEmitter;
    var assign =require('object-assign');
    var AppAPI = require('../utils/appAPI.js');

    var CHANGE_EVENT ='change';
    var _data=[];
    var AppStore= assign({ }, EventEmitter.prototype, {
        setData: function(data){
            console.log("my Data", data);
            _data=data
    }, 
         getData: function(){
            //not getting data in console
            console.log("returning Data", _data);
            return _data;
        },
         emitChange: function(){
            this.emit(CHANGE_EVENT);
        },
        addChangeListener : function(callback){
            this.on('change', callback);
        },
        removeChangeListener: function(callback){
            this.removeListener('change',callback)
        }
    });
    AppDispatcher.register(function(payload){
        var action = payload.action;
        switch(action.actionType){
              case AppConstants.RECEIVE_DATA:
                AppStore.setData(action.data);
                AppStore.emit(CHANGE_EVENT);
                break;
    }
        return true;
    });

    module.exports =AppStore;

我的Main.js是:

var App= require('./components/App');
var React = require('react');
var ReactDom = require('react-dom');
var AppAPI = require('./utils/appAPI.js');

AppAPI.getGenders();
ReactDom.render(
    <App/>,
    document.getElementById('app')
)

和我的APP.JS采用以下格式:

var React =require('react');
var AppActions = require('../actions/AppActions');
var AppStore = require('../stores/AppStore');
function getAppState(){
    return{
        data: AppStore.getData()
    }
}

var App= React.createClass({
    getInitialState: function(){
        console.log(getAppState().data)
        return getAppState()
    },

    componentDidMount: function(){
        AppStore.addChangeListener(this._onChange);
    }, 
    componentWillUnmount: function(){
        AppStore.removeChangeListener(this._onChange);
    },
    render: function(){
},
        _onChange: function(){
            this.setState(getAppState());
        }
});
module.exports =App;

问题:空对象进入console.log(getAppState()。data),因为渲染部分没有等待ajax数据。

请帮助我或给我一些解决这个问题的方法,自从过去3天以来我一直在努力。 提前致谢

2 个答案:

答案 0 :(得分:0)

如果您想避免渲染react组件,因为尚未加载数据,您可以通过这种方式调整组件:

return{
  <div>
  {
    this.state.data?
      <ComponentExample data={this.state.data}/>
    :
      null
  }
  </div>
}

还有其他方法来调整组件呈现,例如使用stateless component,但这种方法可以正常工作。

否则,getInitialState()中有一个空对象不是问题:在第一次渲染时缺少数据是正确的,但是一旦您的API中的数据将被检索,感谢{{ 1}},组件将被重新渲染,因此可以显示_onChange()

答案 1 :(得分:0)

function getAppState(){
    return{
        data: AppStore.getData(),
        status:AppStore.getStatus()
    }
}

将getStatus函数添加到AppStore

render: function(){
   if(this.state.status=='loading')
       return (<div className="loading"></div>);
   if ....
   return (<RealComponent data={this.state.data}></RealComponent>)
},