This is more of an organisation than technical question. I think I may be adding complexity, where a more experienced dev would simplify. I lack that experience, and need help.
It's a menu editor, where I load a menu object from my database into state:
state = {
user_token: ####,
loadingMenu: true,
menu: {} // menu will be fetched into here
}
The object looks like this:
{
menuID: _605c7e1f54bb42972e420619,
brandingImg: "",
specials: "2 for 1 drinks",
langs: ["en", "es"],
items: [
{
id: 0,
type: "menuitem",
isVisible: true,
en: {
name: "sandwich 1",
desc: "Chicken sandwish"
},
es: {
name: "torta 1"
},
price: 10
},
// ...
// ABOUT 25 MORE ITEMS
]
}
The UI allows user to click on and update the items individually. So when they change the text I find myself having to do weird destructuring, like this:
function reducer(state, action) {
if (action.type === UPDATE_NAME) {
const newMenuItems = state.menu.items.map((oldItem) => {
if (oldItem.id === action.payload.id) {
return { ...oldItem, ["en"]: { ...oldItem["en"], name: action.payload.newName } }
// ["en"] for now, but will be dynamic later
}
return oldItem
})
return { ...state, menu: { ...state.menu, items: newMenuItems } }
}
}
This seems like a a bad idea, because I'm replacing the entirety of state with my new object. I'm wondering if there is a better way to organize it?
I know there are immutability managers, and I tried to use immer.js, but ran into an obstacle. I need to map through all my menu items to find the one user wants to edit (matching the ID to the event target's ID). I don't know how else to target it directly, and don't know how to do this:
draft.menu.items[????][lang].name = "Sandwich One"
So again, I'm thinking that my organisation is wrong, as immutability managers should probably make this easy. Any ideas, what I can refactor?