好吧,所以我遇到了 reactjs、flux architecture 和 react-router 的问题。我有以下路线(只是部分路线):
<Route name="prepare-seniors">
<Route name="senior" path=":candidateId" handler={SeniorCandidate}>
<DefaultRoute handler={SeniorProfile}/>
<Route name="senior-recommendations" path="recommends">
<DefaultRoute handler={SeniorRecommends}/>
<Route name="senior-rec-new" path="new"/>
</Route>
</Route>
</Route>
Senior Profile 视图调用 API 来加载个人数据。当您导航到 Recommends 视图时,个人的 ID 用于进行另一个调用以加载推荐。如果我实际上首先查看个人资料页面并导航到推荐页面,它会非常有用。但是,如果我进行硬重新加载,我会得到:
Uncaught Error: Invariant Violation: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.
我意识到这是因为在第一个 API 返回之后调用了调度,它出去并开始更新组件。在它完成之前,推荐页面调用它的 API 并尝试分发它的结果。我在一个论坛上读到 React.addons.batchUpdates 是解决这个问题的一种方法,但我不知道如何让它工作。GitHub 批量更新问题和此处的另一个链接讨论了类似的尝试使用 waitFor。第一个建议通过添加以下内容来调整调度程序:
// assuming a var `flux` containing your Flux instance...
var oldDispatch = flux.dispatcher.dispatch.bind(flux.dispatcher);
flux.dispatcher.dispatch = function(action) {
React.addons.batchedUpdates(function() {
oldDispatch(action);
});
};
但我无法完成这项工作。也许我只是不正确地实施它。
我已经阅读了 Chat 和 TodoMVC 示例。我了解在聊天示例中如何使用 waitFor ......但是它们都使用相同的 API,因此很明显一个会等待另一个。我的问题涉及 API 和调度之间的竞争条件......我不认为 setTimeout 是一个好的解决方案。
我需要了解如何设置调度程序,以便它将调度或 API 调用排队。或者告诉每个组件对其数据进行 API 调用的更好方法,所以我什至没有调度问题。
哦,这是我的 Dispatcher.js 文件,您可以看到它是如何设置的:
'use strict';
var flux = require('flux'),
Dispatcher = require('flux').Dispatcher,
React = require('react'),
PayloadSources = require('../constants/PayloadSources'),
assign = require('object-assign');
//var oldDispatcher = flux.Dispatcher.dispatch.bind(AppDispatcher);
//
//flux.dispatcher.dispatch = function(action) {
// React.addons.batchedUpdates(function() {
// oldDispatcher(action);
// });
//};
var AppDispatcher = assign(new Dispatcher(), {
handleServerAction: function(action) {
var payload = {
source: PayloadSources.SERVER_ACTION,
action: action
};
this.dispatch(payload);
},
handleViewAction: function(action) {
if (!action.type) {
throw new Error('Empty action.type: you likely mistyped the action.');
}
var payload = {
source: PayloadSources.VIEW_ACTION,
action: action
};
this.dispatch(payload);
}
});
module.exports = AppDispatcher;