2

I am creating a shopping list application that gives a user to ability to create a shopping list. Each shopping list that the user creates has the following properties:

key name budget listItem

Nested within the listItem property is an array of objects of list items.

Each list item has the following properties: id: name: price:

Here is a code snippet:

const [shoppingLists, setShoppingList] = useState([
    {key: '1', name: `Khari's Shopping List`, budget: 200, listItems:[
            {id: Math.random().toString(), name:"butter", price:2.00},
            {id: Math.random().toString(), name:"milk", price:2.00},
            {id: Math.random().toString(),  name:"cereal", price: 3.00},
            {id: Math.random().toString(),  name:"chicken", price: 4.00},
            {id: Math.random().toString(),  name:"spaghetti", price: 5.00},
        ], },
    {key: '2', name: `Janae's Shopping List`, budget: 500, listItems:[
            {id: Math.random().toString(), name:"butter2", price:0.00},
            {id: Math.random().toString(), name:"milk2", price:0.00},
            {id: Math.random().toString(),  name:"cereal3", price: 0.00},
            {id: Math.random().toString(),  name:"chicken2", price: 0.00},
            {id: Math.random().toString(),  name:"spaghetti2", price: 0.00},
        ], },

])

What I wish to do is update the price property that is nested in the list item when a user enters a number in the text input. Any ideas on how I can achieve this ?

When a user enters a number in a text input I what to update the price property in the list item array based on the id. I am not sure where to begin and I am hoping for some guidance. Thanks for any help that you can offer.

K.Woods
  • 39
  • 8

1 Answers1

2

In functional component state updates you need to shallowly copy the existing state into a new object, updating the specific object. With more deeply nested state you need to also copy the nested state and update.

Given a specified key, id, and updated price

setShoppingList(lists =>
  lists.map(list =>
    list.key === key
      // Key matches, spread existing state and update list items array
      ? {
          ...list,
          listItems: list.listItems.map(item =>
            item.id === id
              // Item id match, spread existing item and update price
              ? {
                  ...item,
                  price
                }
              // No item id match, pass existing item
              : item
          )
        }
      // No key match, pass existing list
      : list
  )
);

Edit Update Nested State

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Thank you this is very useful I have an idea of where to proceed now ! – K.Woods Jul 24 '20 at 00:59
  • I being searching alot and finally got this, now i am able to nest any level and easily change a (specific or any) value, thanks alot. – Jamal Ud Din Sep 09 '21 at 05:11
  • @DrewReese how can i loop through all item of first .map() function without checking the condition and then in the nested one i want to check the condition and update it??? – Jamal Ud Din Sep 09 '21 at 05:19
  • 1
    @JamalUdDin You'll still need to check a condition on each element of any array you are looping over to know if you will be updating any nested state from there. You'll need to return a new object/array reference for that specific element before you drill deeper into the state structure. – Drew Reese Sep 09 '21 at 05:24
  • @DrewReese ok so like i need to put like (always true) and then go deep inside that abject. Ok i have done and its working fine, Thanks again – Jamal Ud Din Sep 09 '21 at 06:42