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} === {}

您可以通过两种方式解决您的问题。要么将状态初始化为包含它需要的每个 typerow,例如

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
                }
            }
        }
    }
}