I'm trying to figure out how to update an array in an array in react nested state. I already learned about shallow copies but don't get how to implement it in this case.
There is a dispatch function with the useReducer hook to manage an array of objects called "Layer"
interface Layer {
name: string,
data: Item[],
...
}
every Layer holds an array of Items
class Item {
id: number;
...
}
this is my dispatch function:
type ActionType =
| { type: "ADD LAYER"; layer: Layer }
| { type: "ADD ITEM"; item: Item; layer: Layer }
| { type: "UPDATE ITEM"; item: Item; layer: Layer }
| { type: "REMOVE ITEM"; item: Item; layer: Layer };
const [layers, dispatch] = useReducer((state: Layer[], action: ActionType) => {
switch (action.type) {
case "ADD LAYER":
{
if (!state.includes(action.layer))
state.push(action.layer);
return state;
}
case "ADD ITEM":
{
if(!state.find(layer => layer.name === action.layer.name)?.data.find(item => item.id === action.item.id))
state.find(layer => layer.name === action.layer.name)?.data.push(action.item)
return state;
}
case "UPDATE ITEM": {
//implementation missing
return state;
}
case "REMOVE ITEM":
{
const newState = {
...state.map(layer =>
layer.name == action.layer.name
? { ...layer, data: {
...layer.data.filter(({ id }) => id !== action.item.id)
} }
: layer )
};
return newState;
}
default:
throw new Error();
}
}, initialLayers);
look at the REMOVE ITEM case to see what I tried. But this approach make my application crash with the message: Uncaught TypeError: layers.map is not a function
case ADD LAYER and ADD ITEM are working
LayersProvider) while rendering a different component (Layer). To locate the bad setState() call insideLayer, follow the stack trace as described in reactjs.org/link/setstate-in-render"