在组件状态下更改嵌套对象的多个属性值时,我试图应用最佳实践。
我的组件代码当前如下所示:
class App extends Component {
state = {
object: {
a: 10,
b: 7,
c: 12,
}
}
render() {
return (
<div>
<button onClick={this.setState({ object: { a: 5 }})}>change value a </button>
<button onClick={this.setState({ object: { b: 2 }})}>change value b </button>
<button onClick={this.setState({ object: { c: 3 }})}>change value c </button>
</div>
<p>{this.state.object.a}</p>
<p>{this.state.object.b}</p>
<p>{this.state.object.c}</p>
);
}
}
在单击任何按钮之前,您会看到三个按钮,然后在页面上依次显示分别为10
,7
和12
的段落。
单击第一个标记为“更改值a”的按钮后,值b
和c
在我的组件状态对象中被破坏,这仅导致显示5
的值。如果单击第二个按钮,则仅显示2
,并且道具a
和c
消失了。
我了解这种行为,但是我想知道解决它的最佳方法。我想保留它,以便所有值都显示出来,并能够在其他值保留的同时以任何顺序更新它们。
我也很确定我直接在改变状态,我知道这是不好的做法。在这种情况下,我只是不知道正确的做法。
答案 0 :(得分:1)
执行此操作的一种方法是在嵌套...
上使用传播object
运算符,以将{ a: 5 }
的更新与{{1}的先前状态合并}字段:
object
有几种方法可以将其与// Create a new state object, with updated value of "5" for nested field "object.a"
{ object: { ...state.object, a: 5 }}
合并-一种简单的方法是通过传递给setState()
的回调:
setState()
这允许您合并嵌套的this.setState(state => { object: { ...state.object, a: 5 }})
的先前状态,并合并状态,例如object
上的{ a : 5 }
,而无需完全替换其中的所有嵌套object
值您的状态。
对于渲染功能,您可以像这样更新渲染结果:
object
答案 1 :(得分:1)
首先要回答您所说的话, “我正在直接改变状态” 。
由于您正在调用this.setState()
,因此您不是直接在改变状态。
由于您要更新object: {}
的特定部分,因此可以如下使用扩展语法或Object.assign()
:
this.setState({ object: { ...this.state.object, a: 5 } })
或
this.setState({ object: Object.assign({}, this.state.object, { a: 5 }) })
由于您在this.setState()
中呼叫了render
,因此您将获得Maximum call stack exceeded error
。
我可以想到四种解决方法,我将展示其中两种。
onClick={this.setState({
object: { c: 3 }})}
更改为onClick={() => this.setState({ object: { c:
3 }})}