When I have multiple async requests out for data, how can I guarantee the responses won't happen in the same event loop? Those responses will both trigger dispatches from the action creators causing dispatch within a dispatch message.
Note that the data are not dependent on each other so using waitFor()
doesn't do anything.
For example, two components:
let Post = React.createClass({
getInitialState () {
return {
post: PostStore.getPost(postID) //This triggers an API call
}
},
render () {
return (
<Authors/>
);
}
});
let Authors = React.createClass({
getInitialState () {
return {
authors: UserStore.getAuthors() //This also triggers an API call
}
}
});
I get dispatch within a dispatch
invariant every time. Now if I were to bootstrap the data or put UserStore.getAuthors()
dispatch behind the setTimeout(func, 0)
hack it will work fine since it forces the second API call to dispatch on the next event loop. However, I'm sure that at some point I'm going to run into this issue again. For instance, what if I have a twitter feed that updates via API requests on a poll? How can I guarantee that the API request won't come back and interfere with another dispatch?
I can bootstrap data like so:
PostStore.initialize(window.posts);
UserStore.initialize(window.users);
Why doesn't that create a dispatch within a dispatch invariant? Is it not two dispatches at the same time?
Update 11/16/15
I have switch to Redux, which is the better Flux implementation and solves a lot of these problems.
I'm using this implementation so all the dispatch are queued and I never have any problem:
var Dispatcher = require('flux').Dispatcher;
var assign = require('object-assign');
var Constants = require('Constants');
var async = require('async');
var PayloadSources = Constants.PayloadSources;
var dispatcher = new Dispatcher();
var queue = async.queue( function (task, callback) {
var payload = {
source:PayloadSources[task.source],
action: task.action
};
AppDispatcher.dispatch(payload);
callback();
}, 1);
var AppDispatcher = assign(dispatcher, {
handleServerAction: function (action) {
queue.push({source : 'SERVER_ACTION', action : action});
// console.log(queue);
},
handleViewAction: function (action) {
queue.push({source: 'VIEW_ACTION', action : action});
// console.log(queue);
}
});
module.exports = AppDispatcher;