admin管理员组文章数量:1287606
Would appreciate any help here. I have this piece of code which is trying to update my State whenever a form field receives a change. This worked fine in the previous version of React, but after upgrading to the latest version I'm getting the error "Invalid attempt to spread non-iterable instance".
I understand that I need to normalize my State, which I plan to. However, that will involve a significant refactor which I hoping to avoid at the moment with a quick fix.
Error
Code
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 Example:
state = {
controls: {
materials: {
value: "",
materials: [
{
material_type: "",
material: ""
}
],
validation: {
required: true,
minLength: 10
},
valid: false,
touched: false
}
}
}
Would appreciate any help here. I have this piece of code which is trying to update my State whenever a form field receives a change. This worked fine in the previous version of React, but after upgrading to the latest version I'm getting the error "Invalid attempt to spread non-iterable instance".
I understand that I need to normalize my State, which I plan to. However, that will involve a significant refactor which I hoping to avoid at the moment with a quick fix.
Error
Code
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 Example:
state = {
controls: {
materials: {
value: "",
materials: [
{
material_type: "",
material: ""
}
],
validation: {
required: true,
minLength: 10
},
valid: false,
touched: false
}
}
}
Share
Improve this question
edited Jan 31, 2019 at 15:31
Treycos
7,4923 gold badges28 silver badges51 bronze badges
asked Jan 31, 2019 at 15:21
MiscueMiscue
531 gold badge1 silver badge5 bronze badges
7
- 1 Can you show us an exmaple of your state structure ? (And which variable this function changes) – Treycos Commented Jan 31, 2019 at 15:26
-
1
The error means that you've got
...something
andsomething
is not an array or something like an array – Pointy Commented Jan 31, 2019 at 15:28 - Yes. Let me update the post with the state structure. – Miscue Commented Jan 31, 2019 at 15:29
-
Not 100% sure but it looks like it should be
prevState.controls.materials.materials[data.searchInput],
without the...
– Pointy Commented Jan 31, 2019 at 15:31 -
2
probably should be
materials: [ ...material ]
Without the...prevState.controls.materials.materials[data.searchInput]
since you're updating it on the top – adiga Commented Jan 31, 2019 at 15:33
3 Answers
Reset to default 3The error is caused by
[...prevState.controls.materials.materials[data.searchInput],
because you cannot spread a non-iterable object within an array literal.
If you really want to keep with the "immutable" pattern, you should not do:
const material = this.state.controls.materials.materials;
material[data.searchInput].material_type = data.value;
Without the above mutation of the state, the altered copy can be made like this:
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
}
})
}
}
}))
your data structure is not easy to understand so I can not help you more than this example : https://repl.it/@Benoit_Vasseur/SO-Invalid-attempt-to-spread-non-iterable-instance
If I understood correctly you try to spread an object into an array so it does not work. You can spread an array in an array and an object in an object (type must match).
Hope that it helps :)
The error is ing from this line: ...prevState.controls.materials.materials[data.searchInput]
because it's an object. Since you're already updating the materials
array on top, no need to add another item.
You should change this part: materials: [ ...material ]
Here's some code that mimics 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"})
Update: This just fixes the error but @trincot's answer explains how to do this without mutation
本文标签: javascriptInvalid attempt to spread noniterable instanceStack Overflow
版权声明:本文标题:javascript - Invalid attempt to spread non-iterable instance - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741316547a2371947.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论