I'm using React and the trying to use the setState hook to update a value in a quite nested object, as you might have understood from the title 😅
I managed to get it to work somewhat, but instead of getting the original array of objects that I had before, I get an index object as my return value.
So my object that i'm working with looks something like this:
{
category: ""
level: ""
name: ""
rarity: ""
requirements: [ {name: "", customValue: 0 <--- that I wish to update }, {name: "", customValue: 0 }]
}
When I tried to update the state of this value i managed to get it down to this. The index of the property is known.
setItemUpdated((prev) => ({
...prev,
requirements: { ...prev.requirements, [idx]: { ...prev.requirements[idx], customValue: val } },
}));
This works, to some extent. But instead of an [ {}, {} ] I'm getting [ 1:{} 2:{} ]. I understand why I'm getting this, since I'm setting the first requirements as an object, however, when i'm trying to wrap the inside with an array, I'm never getting anything to compile. I really don't know how the syntax for that would be for that.
I tried to search for a similar thread here on SO which no doubt there is, but just couldn't find anything. I'm hoping you can help me out here!
Thank you in advance!
The long hand solution is to simply slice the array before and after the index and spread the object at the index.
setItemUpdated((prev) => ({
...prev,
requirements: [
...prev.requirements.slice(0, idx),
{ ...prev.requirements[idx], customValue: val },
...prev.requirements.slice(idx + 1),
],
}));
was actually working with something similar myself at the moment, the process i'm doing is copying out the state data, editing it based in the input (in your case called prev). Tossing a quick potential answer out here since I just saw this question.
const data = { ...useStateData.data };
data[input.name] = input.value;
setUseStateData({ data});
So you might need to do something like:
data.requirements['name'] = updatedvalue;
Hope that helps -
As you already mentioned, you are trying to spread an array inside an object, which in result fill the object with the index/value pairs of the array.
I'd do instead something like following (in an immutable manner):
setItemUpdated(prev => ({
...prev,
requirements: prev.requirements.map((prevRequirement, index) => index === idx
? {...prev.requirements[idx], customValue: val}
: prevRequirement
),
}));
Which essentially maps over the prev.requirements and if it finds the known index, it replaces/modifies that object, otherwise it returns the prevRequirement from array