ES6/React:为什么我的三重嵌套 setState 更新不起作用?
ES6/React: Why is my triple-nested setState update not working?
我有一个具有三个嵌套属性的状态对象,我需要一次只更新值。所以我使用 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
}
}
}
}
}
假设您的初始状态是:
this.state = {
changedCells: {}
};
那么您的 属性 访问评估如下:
this.state.changedCells
计算为 {}
this.state.changedCells[type]
计算结果为未定义
this.state.changedCells[type][row]
类型错误:无法读取 属性 行未定义
您的代码之前可以正常工作,因为您可以对未定义的对象使用扩展运算符:
{...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
}
}
}
}
}
我有一个具有三个嵌套属性的状态对象,我需要一次只更新值。所以我使用 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
}
}
}
}
}
假设您的初始状态是:
this.state = {
changedCells: {}
};
那么您的 属性 访问评估如下:
this.state.changedCells
计算为 {}
this.state.changedCells[type]
计算结果为未定义
this.state.changedCells[type][row]
类型错误:无法读取 属性 行未定义
您的代码之前可以正常工作,因为您可以对未定义的对象使用扩展运算符:
{...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
}
}
}
}
}