【问题标题】:Invalid attempt to spread non-iterable instance传播不可迭代实例的无效尝试
【发布时间】:2019-06-25 02:28:57
【问题描述】:

在此不胜感激。我有这段代码试图在表单字段收到更改时更新我的​​状态。这在以前版本的 React 中运行良好,但在升级到最新版本后,我收到错误“无效的传播不可迭代实例的尝试”。

我知道我需要使我的状态正常化,这是我计划的。但是,这将涉及重大的重构,我希望通过快速修复来避免目前。

错误

代码

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

【问题讨论】:

  • 你能给我们看一个你的状态结构的例子吗? (以及这个函数改变了哪个变量)
  • 这个错误意味着你有...somethingsomething不是一个数组或类似数组的东西
  • 是的。让我用状态结构更新帖子。
  • 不是 100% 确定,但看起来应该是 prevState.controls.materials.materials[data.searchInput], 没有 ...
  • 可能应该是materials: [ ...material ] 没有...prevState.controls.materials.materials[data.searchInput],因为你在顶部更新它

标签: javascript reactjs


【解决方案1】:

你的数据结构不太容易理解,所以我无法为你提供更多帮助:https://repl.it/@Benoit_Vasseur/SO-Invalid-attempt-to-spread-non-iterable-instance

如果我理解正确,您尝试将一个对象传播到一个数组中,这样它就不起作用了。可以在数组中展开数组,在对象中展开对象(类型必须匹配)。

希望对你有帮助:)

【讨论】:

    【解决方案2】:

    错误来自这一行:...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 的回答解释了如何在没有突变的情况下做到这一点

    【讨论】:

      【解决方案3】:

      错误是由

      引起的
      [...prevState.controls.materials.materials[data.searchInput],
      

      因为您不能在数组字面量中传播不可迭代的对象。

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

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

      没有上述状态的mutation,修改后的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
                      }
                  })
              }
          }
      }))
      

      【讨论】:

        猜你喜欢
        • 2019-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-02
        • 2021-01-28
        • 2019-07-01
        • 1970-01-01
        • 2021-01-14
        相关资源
        最近更新 更多