To be honest I am not even 100% that this is my problem – it could simply be that I have the structure wrong. But this is what I am trying to do:
Team :
{
1 : {
name: "Joe",
items: ['hat', 'gloves']
},
2 : {
name: "Kate",
items: ['bonnet']
}
}
const [team, setTeam] = useState(Team);
There could be any number of people in the team. There could be any number of items in the items collection.
I know the number of the person e.g. 1 for Jim and I know the index of the items array I want to change and the new value.
This is a simplified example but it is exactly the problem.
So, let’s say I want to replace Joe’s gloves with mittens:
function update(teamNumber, itemNumber, newItem) {
let newItems = Team[teamNumber].items.map( (val, idx) => {
if (idx == itemNumber)
{
return newItem;
}
else
{
return val;
}
});
setTeam(
(prevState) => {
return {...prevState,
teamNumber : {
...prevState[teamNumber],
items : newItems
}
};
}
)
}
There are two separate problems:
-
How to update the specific index element in the array. I have not even tried to do that in the state setter – I try to do it separately in the map routine.
-
There seems to be a problem using a variable, teamNumber as a key in the state setter. At least when I run with this code it appears to wipe state (at least nothing is displayed in the bound input field) but if I use a specific number e.g. 1 for teamNumber then it appears to work.
I could live with 1. But 2. is a blocker. (My workaround is to do a clean unlinked copy of the whole object – there are more fields – and replace it completely).
Another approach might be to "flatten the state" – i can see that; but, again, I can’t create a set variable for each team member because they are variable..
Thank you
2
Answers
I would just reset the state like this. It is a little verbose but should do the job. Let me know if you need me to explain this in more depth:
wrap your key in bracket to make it dynamic as Unmitigated mention: