John
John

Reputation: 93

modify and insert new object in array of objects with useState hook

I'm working on a simple order list web app using react hooks, I have an orders state and when the user clicks on a product image in the shopping panel a new object adds to the orders array with quantity property

export const AddOrder = () => {

const [order, insertOrder] = useState([])

let orderHandler = (e, product) => {
    e.preventDefault()
    console.log('orderHandler')
    let newOrder = {
        _id: product._id,
        quantity: 1,
        sellingPrice: product.sellingPrice
    }
    //insertOrder([...order, newOrder])
    insertOrder(prevState => {
      return(
           [ ...prevState, newOrder ])
      })
}

Now when user clicks on a product image:

if the product id exists in order array I want to update the quantity property

otherwise, I want to add a new object to the order array

I know this is kinda simple but I am new with React.js, especially React hooks

I have searched but the answers were a bit confusing to me!

Upvotes: 0

Views: 2154

Answers (3)

Shyam
Shyam

Reputation: 5497

let orderHandler = (e, product) => {
  e.preventDefault();
  let newOrder = {
    _id: product._id,
    quantity: 1,
    sellingPrice: product.sellingPrice,
  };
  // find whether the product already exists
  const isOrderPresent = order.some((item) => item._id === product._id);
  // if found update its quantity 
  if (isOrderPresent) {
    const updatedOrder = order.map((item) => {
      if (item._id === product._id) {
        return {...item, quantity: ++item.quantity};
      }
      return item;
    });
    insertOrder(updatedOrder);
  } else {
    // if not found add the new order along with the existing order
    insertOrder((prevOrderState) => [...prevOrderState, newOrder]);
  }
};

Upvotes: 2

Mr.LeiDeSen
Mr.LeiDeSen

Reputation: 51

insertOrder(prev => {
  return [...prev, newOrder]
})

Upvotes: 0

Ori Drori
Ori Drori

Reputation: 193002

It's easier to work with an object (dictionary) instead of an array, when you need to update items.

Changing order to object, check if the product._id exists on the object. If not, add the item to the object using the product._id as the key. If it does, recreate the object at the product._id, and increment the previous quantity.

Use Object.values() to convert the object to an array, when you wish to render it.

const AddOrder = () => {
  const [order, updateOrder] = useState({})

  const orderHandler = (e, product) => {
    e.preventDefault()
    
    updateOrder(prevState => {
      if(product._id in prevState) {
        return {
          ...prevState,
          [product._id]: {
            ...prevState[product._id],
            quantity: prevState[product._id].quantity + 1
          }
        }
      }
    
      const newOrder = {
        _id: product._id,
        quantity: 1,
        sellingPrice: product.sellingPrice
      }
      
      return { ...prevState, [product._id]: newOrder }
    })
  }
  
  const orderArr = Object.values(order)
  
  // return - render the orderArr
}

Upvotes: 4

Related Questions