I am using Zustand in a Next.js app using TypeScript, For some reason, I get a runtime error message whenever I try to iterate on my state object.
The structure of my car damaged zone object is:
const damagedZones = {
Left: {
front_door:[
{
id: 1,
picture1: 'picture 1 base64 string',
picture2: 'picture 2 base64 string',
comment: 'any comment'
},
{
id: 2,
picture1: 'picture 1 base64 string',
picture2: 'picture 2 base64 string',
comment: 'any comment'
}
],
back_door: [
],
so, imagine I add a new object to my "front_door" array, here is my zustand store and function: In the code below, the dynamic prop "zone" would be my "Left" key of my damagedZones object, and the dynamic prop "element" would be my "front_door" key.
export const useDamagedZones = create<DamagedZonesProps>((set) => ({
damagedZones: damagedZones,
setDamagedZones: (elementItem: damagedItem, zone: string, element: string) => {
set(state => ({
damagedZones: {
...state.damagedZones,
[zone]: {
...state.damagedZones[zone],
[element]: [
...state.damagedZones[zone]?.[element],
elementItem
]
}
}
}))
},
}))
so basically when I trigger this function, I get a runtime error which says:
TypeError: Invalid attempt to spread non-iterable instance. In order to be iterable, non-array objects must have a Symbol.iterator method.
I am not understanding why that is so.... I have tried using an object instead of an array, with an id as key, and it works fine, but it's not super convenient, so an array is the best in this situation, but it doesn't perform as expected....
Alright i figured it out, it is because i misconceived my typescript types for my damagedZone object ! i forgot to mention that one key would be an array :)
it works now that my object type is like so :
type damagedItem = {
id?: number
picture1?: string | null,
picture2?: string | null,
picture3?: string | null,
comment?: string,
}
type DamagedElement = {
[key: string]: damagedItem[]
}
type DamagedZone = {
step1_gauche: DamagedElement,
step1_droite: DamagedElement,
step1_avant: DamagedElement,
step1_arriere: DamagedElement
}
and here is the store useDamagedZones for now :
export const useDamagedZones = create<DamagedZonesProps>((set) => ({
damagedZones: damagedZones,
setDamagedZones: (elementItem: damagedItem, zone: string, element: string) => {
set(state => ({
damagedZones: {
...state.damagedZones,
[zone]: {
...state.damagedZones[zone],
[element]: [
...state.damagedZones[zone]?.[element],
elementItem
]
}
}
}))
},
removeDamagedItem : (zone: string, element: string, id: number ) => {
set(state => ({
damagedZones: {
...state.damagedZones,
[zone]: {
...state.damagedZones[zone],
[element]:
state.damagedZones[zone]?.[element].filter(el => el.id !== id)
}
}
}))
}
}))