如何在REACT和FLUX中创建API调用

Jos*_*ose 16 reactjs reactjs-flux

我是新手做出反应和变化,我很难弄清楚如何从服务器加载数据.我能够从本地文件加载相同的数据,没有任何问题.

所以首先我有这个控制器视图(controller-view.js),它将初始状态传递给视图(view.js)

控制器view.js

var viewBill = React.createClass({
getInitialState: function(){
    return {
        bill: BillStore.getAllBill()
    };
},
render: function(){
    return (
        <div>
            <SubscriptionDetails subscription={this.state.bill.statement} />
        </div>
    );
}
 });
 module.exports = viewBill;
Run Code Online (Sandbox Code Playgroud)

view.js

var subscriptionsList = React.createClass({
propTypes: {
    subscription: React.PropTypes.array.isRequired
},
render: function(){

   return (
        <div >
            <h1>Statement</h1>
            From: {this.props.subscription.period.from} - To {this.props.subscription.period.to} <br />
            Due: {this.props.subscription.due}<br />
            Issued:{this.props.subscription.generated}
        </div>
    );
}
 });
 module.exports = subscriptionsList;
Run Code Online (Sandbox Code Playgroud)

我有一个动作文件,可以为我的应用程序加载INITAL数据.因此,这是不是作为用户操作调用的数据,而是在控制器视图中从getInitialState调用的数据

InitialActions.js

var InitialiseActions = {
initApp: function(){
    Dispatcher.dispatch({
        actionType: ActionTypes.INITIALISE,
        initialData: {
            bill: BillApi.getBillLocal() // I switch to getBillServer for date from server
        }
    });
}
};
module.exports = InitialiseActions;
Run Code Online (Sandbox Code Playgroud)

然后我的数据API看起来像这样

api.js

var BillApi = {
getBillLocal: function() {
    return billed;
},
getBillServer: function() {
    return $.getJSON('https://theurl.com/stuff.json').then(function(data) {

        return data;
    });
}
};
module.exports = BillApi;
Run Code Online (Sandbox Code Playgroud)

这是商店 store.js

var _bill = [];
var BillStore = assign({}, EventEmitter.prototype, {
addChangeListener: function(callback) {
    this.on(CHANGE_EVENT, callback);
},
removeChangeListener: function(callback) {
    this.removeListener(CHANGE_EVENT, callback);
},
emitChange: function() {
    this.emit(CHANGE_EVENT);
},
getAllBill: function() {
    return _bill;
}
});

Dispatcher.register(function(action){
switch(action.actionType){
    case ActionTypes.INITIALISE:
        _bill = action.initialData.bill;
        BillStore.emitChange();
        break;
    default:
        // do nothing
}
});

module.exports = BillStore;
Run Code Online (Sandbox Code Playgroud)

正如我之前提到的,当我在操作中使用BillApi.getBillLocal()在本地加载数据时,一切正常.但是当我改为BillApi.getBillServer()时,我在控制台中得到了followind错误...

Warning: Failed propType: Required prop `subscription` was not specified in     `subscriptionsList`. Check the render method of `viewBill`.
Uncaught TypeError: Cannot read property 'period' of undefined
Run Code Online (Sandbox Code Playgroud)

我还将一个console.log(数据)添加到BillApi.getBillServer(),我可以看到数据是从服务器返回的.但它显示后,我得到在控制台的警告,我认为可能是问题.有人可以提供一些建议或帮我解决吗?对不起这么长的帖子.

UPDATE

我对api.js文件进行了一些更改(请在此处查看更改和DOM错误plnkr.co/edit/HoXszori3HUAwUOHzPLG),因为有人建议问题是由于我如何处理承诺.但它似乎仍然是你在DOM错误中看到的相同问题.

col*_*ace 8

这是一个异步问题.使用$.getJSON().then()还不够.由于它返回一个promise对象,你必须通过执行类似的操作来处理调用时的promiseapi.getBill().then(function(data) { /*do stuff with data*/ });

我使用以下代码创建了一个CodePen示例:

function searchSpotify(query) {
  return $.getJSON('http://ws.spotify.com/search/1/track.json?q=' + query)
  .then(function(data) {
    return data.tracks;
  });  
}

searchSpotify('donald trump')
.then(function(tracks) {
  tracks.forEach(function(track) {
    console.log(track.name);
  });
});
Run Code Online (Sandbox Code Playgroud)