使用react将元素添加到属于状态的列表中

时间:2019-05-16 18:45:34

标签: javascript reactjs

我的状态上有这个json变量:

this.state = {
        type:
        {
            name: '',
            type2: {
                atribute: '',
                parameter: [
                    {
                        value: '',
                        classtype: ''
                    }
                ],
                name: '',
                atribute1: '',
                atribute2: ''
            }
        }
    }

我要做的是将元素添加到参数列表中,该列表在开始时为空。

我所做的是这样:

addParams = () => {

    let newParam = {
        value: this.state.type.type2.parameter.value,
        classtype: this.state.type.type2.parameter.classtype
    };

    /** */
    this.setState(prevState => ({


        type: {

            // keep all the other key-value pairs of type
            ...prevState.type,

            type2: {

                ...prevState.type.type2,

                //this is supposed to add an element to a list
                parameter: [...prevState.type.type2.parameter, newParam]
            }
        }
    }))  
}

但是当执行最后一行代码时,出现以下错误:

  

未捕获的TypeError:散布不可迭代实例的无效尝试   散布列表时

我不知道为什么这不起作用,因为该参数确实是一个列表。

2 个答案:

答案 0 :(得分:0)

如果this.state.type.type2.parameter是一个数组,那么为什么要引用它的属性:

let newParam = {
    value: this.state.type.type2.parameter.value,
    classtype: this.state.type.type2.parameter.classtype
};

我不认为您的状态像您期望的那样结构化,似乎您在代码中的某个时刻用对象替换了该数组。我建议react-devtools帮助您跟踪状态的变化。

这不是完全正确的答案,但我强烈建议使用immerjs进行这些纯嵌套的更新。我几乎从不建议添加第三方库作为解决方案,但是沉浸感是轻量级的,并且会改变生活。它导出一个称为Produce的函数,并使用一个名为Proxy的概念来执行被写为变异的纯更新。

具有沉浸感(并且已修复错误),您的代码将变为:

const newParam = {
    value: this.state.type.type2.parameter.value,
    classtype: this.state.type.type2.parameter.classtype
};

this.setState(produce(draftState => {
  draftState.type.type2.parameter.push(newParam);
}))

它使您可以编写更简洁的代码,这些代码更易于阅读。是的,我知道看起来就像是一种突变,但这不是100%纯的突变。

答案 1 :(得分:0)

尝试一下:

 this.setState(prevState => {
        return {
            ...prevState,
            type: {
                ...prevState.type,
                type2: {
                    ...prevState.type.type2,
                    parameter: [...prevState.type.type2.parameter, newParam]
                }
            }
        }

    )