正确处理多个连续状态更新
Proper handling of multiple sequential state updates
这个例子有点做作,但请耐心等待。假设我在React组件中有两个成员函数:
var OrderApp = React.createClass({
getInitialState: function() {
return {
selectedOrders: {},
selectedLineItems: {}
};
},
setOrderSelected: function(order, newSelectedState) {
var mutation = {};
mutation[order.id] = {$set: newSelectedState};
var newSelectedOrders = React.addons(this.state.selectedOrders, mutation);
_.each(order.lineItems, function(lineItem) {
setLineItemSelected(lineItem, newSelectedState);
});
this.setState({selectedOrders: newSelectedOrders});
},
setLineItemSelected: function(lineItem, newSelectedState) {
var mutation = {};
mutation[lineItem.id] = {$set: newSelectedState};
var newSelectedLineItems = React.addons(this.state.selectedLineItems, mutation);
this.setState({seelctedLineItems: newSelectedLineItems});
}
});
在调用OrderApp.setOrderSelected(order,true)完成时,在我的组件状态中,只有最后一个lineItem selected状态似乎发生了更改。我猜这是因为React正在批处理对setState的调用,所以当我调用时
var newSelectedLineItems = React.addons(this.state.selectedLineItems, mutation);
在第二个函数中,我每次都会获取原始状态,所以只有最后一个突变生效。
我应该收集父函数中的所有状态突变,并且只调用setState一次吗?这对我来说有点笨拙,我想知道我是否错过了一个更简单的解决方案。
在组件内的给定执行线程中,不应多次调用this.setState
。
所以你有几个选择:
使用forceUpdate而不是setState
您不必使用this.setState
-您可以直接修改状态,并在完成后使用this.forceUpdate
。
这里要记住的主要一点是,一旦开始直接修改this.state
,就应该将其视为受污染。IE:在调用this.forceUpdate
之前,不要使用您知道已修改的状态或属性。这通常不是问题。
当您处理this.state
中的嵌套对象时,我绝对喜欢这种方法。就我个人而言,我不是React.addons.update
的超级粉丝,因为我觉得它的语法非常笨拙。我更喜欢直接修改forceUpdate
。
创建一个传递的对象,直到最终在setState中使用它
收集所有更改的对象,在执行线程结束时传递给this.setState
。
不幸的是,这是浅合并的一个问题。您必须收集更新,并一次性应用它们。
觉得有点笨重
这是一个非常好的迹象,表明您应该使用mixin!这个代码看起来很糟糕,但当你使用它时,你可以假装它看起来很漂亮
var React = require('react/addons');
var UpdatesMixin = {
componentDidMount: function(){
this.__updates_list = [];
},
addUpdate: function(update){
this.__updates_list.push(update);
if (this.__updates_list.length === 1) {
process.nextTick(function(){
if (!this.isMounted()) {
this.__updates_list = null;
return;
}
var state = this.__updates_list.reduce(function(state, update){
return React.addons.update(state, update);
}, this.state);
this.setState(state);
this.__updates_list = [];
}.bind(this));
}
}
};
中的必需
它缓冲所有同步发生的更新,将它们应用于this.state,然后执行setState。
用法如下(完整演示请参阅requirebin)。
this.addUpdate({a: {b: {$set: 'foo'}};
this.addUpdate({a: {c: {$set: 'bar'}};
有些地方可以对其进行优化(例如,通过合并更新对象),但您可以稍后在不更改组件的情况下进行优化。
- Web应用程序,将成员状态更新为其他成员
- Universal React/redux未在状态更新时呈现
- React.js组件中的状态更新在我的页面下留下了空白
- Ajax/Javascript用户状态更新
- 使用ReactJS使用Redux的简单状态更新事件
- Yii:TbCollapse 多链接(href = #collapse 并将状态更新为 be=“1”)
- 当 redux 状态更新时,在组件上调用 forceUpdate()
- 如何更改输入字段值,使其不会在每次更改时贯穿整个 Redux 状态更新周期
- 使用 Google 表格中列出的地址发送单件状态更新电子邮件
- 评论仅发布到最新的状态更新
- 强制 Twitter Epi 库发布状态更新,即使它是上一条推文的副本
- 使用Facebook javascript sdk获取最新的5个状态更新
- 正确处理多个连续状态更新
- 将状态更新到输入字段
- 如何在JavaScript中创建Twitter状态更新,并从中接收响应
- 如何从web url加载元数据,类似于facebook在状态更新时发布url的做法.
- Onkeyup或onkeypress javascript事件问题-密码状态更新
- WshShell运行不等待,但执行状态更新(运行vs执行问题)
- Web服务——异步执行和状态更新
- 点击后显示FB状态更新弹出窗口