[英]ReactJS: Update nested state object properties without replacing whole object using setState()
I am trying to apply best practices when changing multiple property values of a nested object in my component's state.我正在尝试在组件状态下更改嵌套对象的多个属性值时应用最佳实践。
My component code currently looks like this:我的组件代码目前如下所示:
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>
);
}
}
Before any button is clicked, you see three buttons followed by paragraphs reading 10
, 7
and 12
on the page.在单击任何按钮之前,您会在页面上看到三个按钮,然后是阅读10
、 7
和12
的段落。
Once I click the first button labeled "change value a", value b
and c
are destroyed in my components state object which causes only the value of 5
to show.单击标记为“更改值 a”的第一个按钮后,我的组件状态对象中的值b
和c
被销毁,这会导致仅显示值5
。 If I click the second button, then only 2
will show and prop a
and c
are gone.如果我单击第二个按钮,则只有2
将显示并且 prop a
和c
消失了。
I understand the behaviour, however I would like to know the best way to solve it.我理解这种行为,但是我想知道解决它的最佳方法。 I want to keep it so all the values showing, and be able to update them in any order while the other values remain.我想保留它以便显示所有值,并且能够在保留其他值的同时以任何顺序更新它们。
I am also pretty sure I am mutating the state directly and I know this is bad practice.我也很确定我是直接改变状态,我知道这是不好的做法。 I just don't know the right practice in this situation.在这种情况下,我只是不知道正确的做法。
First to address what you said, "I am mutating the state directly" .首先解决你所说的, “我正在直接改变状态” 。
You are are not mutating state directly since you are calling this.setState()
.您没有直接改变状态,因为您正在调用this.setState()
。
Since you want to update a specific part of object: {}
, you can use the spread syntax or Object.assign()
as follows:由于您要更新object: {}
的特定部分object: {}
,您可以使用传播语法或Object.assign()
如下:
this.setState({ object: { ...this.state.object, a: 5 } })
or或者
this.setState({ object: Object.assign({}, this.state.object, { a: 5 }) })
Because you called this.setState()
in render
, you will get the Maximum call stack exceeded error
.因为你在render
调用了this.setState()
,你会得到Maximum call stack exceeded error
。
I can think of four ways to solve this, I'll show two of those.我可以想到四种方法来解决这个问题,我将展示其中的两种。
onClick={this.setState({ object: { c: 3 }})}
to onClick={() => this.setState({ object: { c: 3 }})}
将此onClick={this.setState({ object: { c: 3 }})}
更改为onClick={() => this.setState({ object: { c: 3 }})}
One way to do this would be by using the spread ...
operator on the nested object
to merge the update of say { a: 5 }
, with the prior state of the object
field:一种方法是在嵌套object
上使用 spread ...
运算符将 say { a: 5 }
的更新与object
字段的先前状态合并:
// Create a new state object, with updated value of "5" for nested field "object.a"
{ object: { ...state.object, a: 5 }}
There are a few ways to incorporate this with setState()
- one simple way is via a callback passed to setState()
:有几种方法可以将其与setState()
合并 - 一种简单的方法是通过传递给setState()
的回调:
this.setState(state => { object: { ...state.object, a: 5 }})
This allow you to merge the nested object
s prior state, with the state changes such as { a : 5 }
on object
, without completely replacing all the nested object
value in your state.这使您可以合并嵌套object
事先状态,随着国家的变化,如{ a : 5 }
的object
,而没有完全更换所有的嵌套的object
在你的状态值。
In the case of your render function, you could update the rendered result like so:对于渲染函数,您可以像这样更新渲染结果:
render() {
return (
<div>
<button onClick={ () => this.setState(state => { object: { ...state.object, a: 5 }})}>change value a </button>
<button onClick={ () => this.setState(state => { object: { ...state.object, b: 2 }})}>change value b </button>
<button onClick={ () => this.setState(state => { object: { ...state.object, c: 5 }})}>change value c </button>
</div>
<p>{this.state.object.a}</p>
<p>{this.state.object.b}</p>
<p>{this.state.object.c}</p>
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.