我有一个具有三个嵌套属性的状态对象,我需要一次仅更新值。所以我使用ES6扩展语法来更新状态,但出于某种原因,每当我运行它时,它都会给我未定义的属性类型错误。
当我只有两个嵌套属性时,它工作正常。有什么问题?
method(type, row, col) {
this.setState({
changedCells: {
...this.state.changedCells,
[type]: {
...this.state.changedCells[type],
[row]: {
...this.state.changedCells[type][row],
[col]: true
}
}
}
}
}
当changedCells状态最初为空时。并且setState方法是这样的,用星号表示,它运行正常。但是在我的第一个例子中,cellState为空,而type =' wood',row = 0,col = 0,它不起作用,但在第二个例子中起作用。
method(type, row, col) {
this.setState({
changedCells: {
...this.state.changedCells,
[type]: {
...this.state.changedCells[type],
[row]: {
...this.state.changedCells[row], ***CHANGED***
[col]: true
}
}
}
}
}
答案 0 :(得分:2)
假设您的初始状态为:
this.state = {
changedCells: {}
};
然后您的财产访问评估如下:
this.state.changedCells
评估为{}
this.state.changedCells[type]
评估为未定义
this.state.changedCells[type][row]
TypeError:无法读取未定义的属性行
您的代码之前有效,因为您可以在undefined上使用spread运算符:
{...undefined} === {}
您可以通过两种方式解决问题。初始化状态以包含它需要的每个type
和row
,例如
this.state = {
changedCells: {
typeA: {
row1: {
col1: false
}
}
}
}
等等。如果你有一套明确定义的类型,行和列,这很好,但如果你有很多或者不知道他们的名字,那就不切实际了。
另一个选项是在对象可能未定义时提供默认的空对象:
method(type, row, col) {
this.setState({
changedCells: {
...this.state.changedCells,
[type]: {
...this.state.changedCells[type],
[row]: {
...(this.state.changedCells[type] || {})[row],
[col]: true
}
}
}
}
}
有一些工具可以让您的生活更轻松。您可以使用lodash get
来检索属性,并提供默认值。
method(type, row, col) {
this.setState({
changedCells: {
...(_.get(this.state, "changedCells", {})),
[type]: {
...(_.get(this.state, ["changedCells", type], {})),
[row]: {
...(_.get(this.state, ["changedCells", type, row], {})),
[col]: true
}
}
}
}
}