Javascript React,Flux,React路由器调度错误-可能的解决方案?
好吧,我被reactjs、flux架构和ReactRouter的问题困住了。我有以下路线(只是部分路线): 我意识到这是因为调度是在第一个API返回后被调用的,该API返回并开始更新组件。在完成推荐之前,页面调用其API并尝试发送其结果。我在一个论坛上读到React.addons.batchUpdates是解决这个问题的一种方法,但我不知道如何让它工作。这里的另一个链接讨论了类似的内容。第一个建议通过添加以下内容来调整dispatcher:Javascript React,Flux,React路由器调度错误-可能的解决方案?,javascript,reactjs,reactjs-flux,flux,react-router,Javascript,Reactjs,Reactjs Flux,Flux,React Router,好吧,我被reactjs、flux架构和ReactRouter的问题困住了。我有以下路线(只是部分路线): 我意识到这是因为调度是在第一个API返回后被调用的,该API返回并开始更新组件。在完成推荐之前,页面调用其API并尝试发送其结果。我在一个论坛上读到React.addons.batchUpdates是解决这个问题的一种方法,但我不知道如何让它工作。这里的另一个链接讨论了类似的内容。第一个建议通过添加以下内容来调整dispatcher: // assuming a var `flux` co
// 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不是一个好的解决方案
我需要的是了解如何设置dispatcher,使其能够对dispatch或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;
好的,首先我要说的是,我现在正在学习反应和流量,我绝对不是专家。不过我还是要试一试: 从您所说的,听起来您有两个异步操作触发关闭,然后当它们返回尝试发送调度消息时,调度调用从两个独立的aync webservice调用触发两次所引起的问题 我不认为批处理更新在这种情况下会有帮助,因为这在很大程度上取决于时间(即,如果它已将重新渲染排队,并等待机会在第二次调用时执行,则批处理可能会成功,但是如果它在更新中出现,则您所处的位置与现在完全相同) 我认为这里的实际问题来自于这些行为是如何/何时触发的(你在文章末尾简要提到了这一点)。听起来像是从React组件渲染调用触发动作(有点像延迟加载)。这正是Flux试图避免的事情,因为这种模式很容易导致应用程序流中出现无限循环或奇怪的状态/模式 正如您在描述中提到的,您可能需要提前触发此加载,而不是从单个组件触发此加载,从我所知的一点来看,我建议在调用核心组件上的React.render之前进行此操作。如果您查看示例聊天应用程序,他们会在以下方面执行类似操作:
ChatExampleData.init();//将示例数据加载到本地存储中
ChatWebAPIUtils.getAllMessages();
反应(
,
document.getElementById('react')
);
因此,我建议遵循上述模式,在向客户机显示加载微调器的同时,预先加载任何初始数据
或者,根据您的技术堆栈,您可以首先在服务器上进行渲染(ReactJS.Net的节点示例.Net版本),这样在客户端启动时就不会有延迟(如果这是一个问题,您还可以避免搜索引擎索引的所有有趣业务(顺便说一句,我没有尝试过这两种方法,请阅读相关内容).是的,我注意到他们在聊天时是这样处理的,但我不确定当组件根据其父组件状态/信息发生变化时,这将如何工作。我的意思是,如果我每次都调用完全相同的API,那么这将起作用,但当我调用的API根据给定的道具发生变化时,情况又会如何呢……例如,我使用的是特定的data作为搜索参数?遗憾的是,我不能在这个项目中使用服务器端渲染,因为我工作的公司不想在服务器上使用node,而只是想使用grunt来构建静态文件,然后可以提供给服务器。哦,我要提到的是,我删除了一个在actions creator中调用的子操作,在调用API之前,它开始工作。主要是因为一个API速度慢,我不再有冲突。基本上,有一个动作会说从服务器请求数据并设置微调器,因为调用API的时间大约相同,我得到了调度错误。但这仍然不能回答我的问题当我有两个API几乎同时返回时,我仍然会得到一个分派错误。对不起,最后一条评论。我没有尝试在render方法中执行此操作,但在ComponentWillReceiveProps方法中执行此操作,因此我不确定这是否仍然是一个反模式…查看它们的图表是唯一应该命中操作c的事情视图中的reators是“用户交互”所以这仍然可能是错误的。是的,我同意可能从组件WillReceiveProps中删除操作。我刚刚发现这篇文档是关于您正在尝试做的事情吗?如果这些数据需要存储在存储中,我认为您可能需要将此状态提升到父视图控制器组件的更高级别,如前所述o生成一个操作来加载所有相关数据。实际上,您可能需要使这两个调用相互依赖(因为听起来它们都有助于组件的新状态)。
// 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);
});
};
'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;
ChatExampleData.init(); // load example data into localstorage
ChatWebAPIUtils.getAllMessages();
React.render(
<ChatApp />,
document.getElementById('react')
);