Home > Back-end >  How to update value within an array in react state?
How to update value within an array in react state?

Time:02-21

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' }
        )
    })));
};
  • Related