I am trying to update values within state array.
Initial state values are like:
const [itemList, setItemList] = useState([
{
"id": "0",
"items": [
{
"key": "Player name",
"value": "Sandy",
"type": "trained"
},
{
"key": "Player status",
"value": "status here",
"type": "untrained"
}
]
},
{
"id": "1",
"items": [
{
"key": "Check Number",
"value": "0027858403",
"type": "untrained"
},
{
"key": "Check Date",
"value": "01/22/2010",
"type": "trained"
}
]
} ]);
I want to update value for array element 'type' set this from 'untrained to trained' by using 'id' element of array.
For Ex: On button click, I want to update 'type: trained' for 2nd array element where 'key = Check Number'.
My function for this is like below:
onClickHandler=(id, data)=>{
setItemList((prev)=>prev.map((item)=>{
if(item.id === id){
item.items.map((itm)=>{
if(itm.key === data){
return {...itm,type: 'trained'}
}
else{
return itm;
}
})
}
else{
return item;
}
}))
}
so, onClick={onClickHandler(1, 'Check Number')} where '1' is array id and 'Check Number' is value for 'key' element.
Final output should look like this:
const [itemList, setItemList] = useState([
{
"id": "0",
"items": [
{
"key": "Player name",
"value": "Sandy",
"type": "trained"
},
{
"key": "Player status",
"value": "status here",
"type": "untrained"
}
]
},
{
"id": "1",
"items": [
{
"key": "Check Number",
"value": "0027858403",
"type": "trained"
},
{
"key": "Check Date",
"value": "01/22/2010",
"type": "trained"
}
]
} ]);
CodePudding user response:
You need to unconditionally return from inside the mapper. If the ID matches, return a new object, otherwise return the existing object.
You almost certainly don't need to use the callback version either, since this is a click handler.
onClickHandler = (id, key) => {
setItemList(itemList.map(obj => obj.id !== id ? obj : ({
...obj,
items: obj.items.map(
item => item.key !== key ? item : { ...itm, type: 'trained' }
)
})));
};