this.setState 没有像我期望的那样合并状态

2022-01-31 00:00:00 reactjs javascript

我有以下状态:

this.setState({ selected: { id: 1, name: 'Foobar' } });  

然后我更新状态:

this.setState({ selected: { name: 'Barfoo' }});

由于 setState 假设要合并,我希望它是:

Since setState is suppose to merge I would expect it to be:

{ selected: { id: 1, name: 'Barfoo' } }; 

但是它却吃掉了 id 并且状态是:

But instead it eats the id and the state is:

{ selected: { name: 'Barfoo' } }; 

这是预期的行为吗?仅更新嵌套状态对象的一个​​属性的解决方案是什么?

Is this expected behavior and what's the solution to update only one property of a nested state object?

推荐答案

我认为 setState() 不做递归合并.

I think setState() doesn't do recursive merge.

您可以使用当前状态 this.state.selected 的值来构造一个新状态,然后在其上调用 setState():

You can use the value of the current state this.state.selected to construct a new state and then call setState() on that:

var newSelected = _.extend({}, this.state.selected);
newSelected.name = 'Barfoo';
this.setState({ selected: newSelected });

我在这里使用了函数 _.extend() 函数(来自 underscore.js 库),通过创建一个它的浅拷贝.

I've used function _.extend() function (from underscore.js library) here to prevent modification to the existing selected part of the state by creating a shallow copy of it.

另一种解决方案是编写 setStateRecursively() 对新状态进行递归合并,然后用它调用 replaceState():

Another solution would be to write setStateRecursively() which does recursive merge on a new state and then calls replaceState() with it:

setStateRecursively: function(stateUpdate, callback) {
  var newState = mergeStateRecursively(this.state, stateUpdate);
  this.replaceState(newState, callback);
}

相关文章