传播非迭代实例的尝试无效

时间:2019-01-31 15:21:24

标签: javascript reactjs

在此感谢您的任何帮助。我有这段代码,它试图在表单字段收到更改时更新我的​​州。在React的先前版本中,此方法运行良好,但是在升级到最新版本后,我收到错误消息“无效的尝试来传播不可迭代的实例”。

我了解我需要规范我的国家。但是,这将涉及重大的重构,我希望此刻可以通过快速修复来避免。

错误

enter image description here

代码

handleMaterialTypeChange = (event, data) => {
    const material = this.state.controls.materials.materials;
    material[data.searchInput].material_type = data.value;

    this.setState(prevState => ({
        controls: {
            ...prevState.controls,
            materials: {
                ...prevState.controls.materials,
                materials: [
                    ...prevState.controls.materials.materials[data.searchInput],
                    ...material
                ]
            }
        }
    }));
};

状态示例:

state = {
    controls: {
        materials: {
            value: "",
            materials: [
                {
                    material_type: "",
                    material: ""
                }
            ],
            validation: {
                required: true,
                minLength: 10
            },
            valid: false,
            touched: false
        }
    }
}

3 个答案:

答案 0 :(得分:3)

该错误是由引起

[...prevState.controls.materials.materials[data.searchInput],

因为您不能在数组文字中散布不可迭代的对象。

如果你真的想保持与“不变”的模式,你不应该做的:

const material = this.state.controls.materials.materials;
material[data.searchInput].material_type = data.value;

在没有上述状态的变异的情况下,更改后的 copy 可以如下所示:

setState(prevState => ({
    controls: {
        ...prevState.controls,
        materials: {
            ...prevState.controls.materials,
            materials: Object.assign([], {
                ...prevState.controls.materials.materials,
                [data.searchInput]: {
                    ...state.controls.materials.materials[data.searchInput],
                    material_type: data.value
                }
            })
        }
    }
}))

答案 1 :(得分:1)

您的数据结构不容易理解,因此除了这个示例之外,我不能为您提供更多帮助:https://repl.it/@Benoit_Vasseur/SO-Invalid-attempt-to-spread-non-iterable-instance

如果我正确理解,您尝试将一个对象散布到一个数组中,因此它不起作用。您可以在一个数组中散布一个数组,在一个对象中散布一个对象(类型必须匹配)。

希望它会有所帮助:)

答案 2 :(得分:0)

错误来自以下行:...prevState.controls.materials.materials[data.searchInput],因为它是一个对象。由于您已经在顶部更新了materials数组,因此无需添加其他项。

您应该改变这部分:materials: [ ...material ]

以下是一些类似于setState的代码

handleMaterialTypeChange = (event, data) => {
  const material = state.controls.materials.materials;
  material[data.searchInput].material_type = data.value;

  setState(prevState => ({
    controls: {
      ...prevState.controls,
      materials: {
        ...prevState.controls.materials,
        materials: [
          ...material // here
        ]
      }
    }
  }));
};

const setState = (fn) => {
  console.log(fn(state))
}

const state = {controls:{materials:{value:"",materials:[{material_type:"",material:""}],validation:{required:true,minLength:10},valid:false,touched:false}}}

handleMaterialTypeChange(null, {searchInput: 0,value: "newMaterial"})

更新:这只是修复了错误,但@trincot的回答说明了如何做到无变异