当我声明以下初始状态时:
getInitialState: function() {
return {
isValid: false,
metaData: {
age: 12,
content_type: 'short_url'
}
};
},
和我用setState
更新状态,像这样:
...
let newMetaData = { age: 20 };
...
this.setState({
isValid: true,
metaData: newMetaData
});
...
生成的this.state.metadata
对象只定义了年龄。但据我所知,this.setState()
将它的参数合并到现有状态。为什么它在这里不起作用,这不是应该是循环合并吗?
是否有一种方法来合并新的对象属性状态对象属性在React/ES6?
setState
执行浅合并。如果元数据是平面的:
this.setState({
metaData: Object.assign({}, this.state.metaData, newMetaData),
});
或者如果使用spread:
this.setState({
metaData: { ...this.state.metaData, ...newMetaData },
});
如果你只需要更新一个属性,另一种方法是:
this.setState({
metaData: {
...this.state.metaData,
age: 20
}
})
setState也可以接受一个函数,该函数接收一个state参数,您可以使用lodash merge来进行深度合并。
setState(state => merge(state, yourPartialObjectToBeDeepMerged));
这里有一个棘手的解决方案
const [complexObject, setComplexObject] = useState({a:{b:{c:1}}})
setComplexObject((s)=>{
s.a.b.c = 2
return {...s}
})
它是如何工作的?
对象是引用。如果您使用s.a.b.c = 2
,这将更新状态,但组件不呈现,所以dom不会改变。
然后我们需要一种方式来呈现组件。如果您使用setComplexObject(s=>s)
,它将不会触发渲染,因为尽管ComplexObject的内部确实发生了变化,但引用仍然指向同一个对象。
所以我们需要ES6扩展运算符来重建一个对象{...s}