Pic*_*els 154 javascript reactjs
我有以下状态:
this.setState({ selected: { id: 1, name: 'Foobar' } });
Run Code Online (Sandbox Code Playgroud)
然后我更新状态:
this.setState({ selected: { name: 'Barfoo' }});
Run Code Online (Sandbox Code Playgroud)
由于setState被假定为合并,我希望它是:
{ selected: { id: 1, name: 'Barfoo' } };
Run Code Online (Sandbox Code Playgroud)
但相反它吃了id,状态是:
{ selected: { name: 'Barfoo' } };
Run Code Online (Sandbox Code Playgroud)
这是预期的行为,是什么解决方案只更新嵌套状态对象的一个属性?
and*_*opp 141
我认为setState()不做递归合并.
您可以使用当前状态的值this.state.selected来构造新状态,然后调用setState():
var newSelected = _.extend({}, this.state.selected);
newSelected.name = 'Barfoo';
this.setState({ selected: newSelected });
Run Code Online (Sandbox Code Playgroud)
我在这里使用了函数_.extend()函数(来自underscore.js库)来防止selected通过创建它的浅表副本来修改状态的现有部分.
另一个解决方案是编写setStateRecursively()哪个在新状态上进行递归合并然后replaceState()使用它进行调用:
setStateRecursively: function(stateUpdate, callback) {
var newState = mergeStateRecursively(this.state, stateUpdate);
this.replaceState(newState, callback);
}
Run Code Online (Sandbox Code Playgroud)
小智 96
不动性助手最近被添加到React.addons,所以你可以做以下事情:
var newState = React.addons.update(this.state, {
selected: {
name: { $set: 'Barfoo' }
}
});
this.setState(newState);
Run Code Online (Sandbox Code Playgroud)
Immutability helpers文档:http: //facebook.github.io/react/docs/update.html
bga*_*npl 34
由于许多答案使用当前状态作为合并新数据的基础,我想指出这可能会破坏.状态更改已排队,并且不会立即修改组件的状态对象.因此,在处理队列之前引用状态数据将为您提供过时数据,这些数据不会反映您在setState中所做的挂起更改.来自文档:
setState()不会立即改变this.state,但会创建挂起状态转换.调用此方法后访问this.state可能会返回现有值.
这意味着在后续调用setState时使用"当前"状态作为参考是不可靠的.例如:
如果需要使用当前状态(例如,将数据合并到嵌套对象中),setState或者接受函数作为参数而不是对象; 在对state进行任何先前的更新之后调用该函数,并将该状态作为参数传递 - 因此,这可以用于使原子更改保证遵守先前的更改.
Rya*_*ton 10
我不想安装另一个库,所以这是另一个解决方案.
代替:
this.setState({ selected: { name: 'Barfoo' }});
Run Code Online (Sandbox Code Playgroud)
改为:
var newSelected = Object.assign({}, this.state.selected);
newSelected.name = 'Barfoo';
this.setState({ selected: newSelected });
Run Code Online (Sandbox Code Playgroud)
或者,感谢评论中的@ icc97,更简洁但可读性更低:
this.setState({ selected: Object.assign({}, this.state.selected, { name: "Barfoo" }) });
Run Code Online (Sandbox Code Playgroud)
另外,要明确的是,这个答案并没有违反@bgannonpl上面提到的任何问题.
基于@bgannonpl答案保留以前的状态:
Lodash示例:
this.setState((previousState) => _.merge({}, previousState, { selected: { name: "Barfood"} }));
Run Code Online (Sandbox Code Playgroud)
要检查它是否正常工作,可以使用第二个参数函数回调:
this.setState((previousState) => _.merge({}, previousState, { selected: { name: "Barfood"} }), () => alert(this.state.selected));
Run Code Online (Sandbox Code Playgroud)
我用过,merge因为extend丢弃了其他属性.
反应不变性的例子:
import update from "react-addons-update";
this.setState((previousState) => update(previousState, {
selected:
{
name: {$set: "Barfood"}
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
65747 次 |
| 最近记录: |