I have an array of objects containing a list of items. The items are updated from a dynamic form field. Below is the item object
{ product_id: { name: "", price: 0, hsn: "" }, quantity: 0, cgst_amount: 0, sgst_amount: 0, igst_amount: 0, total: 0 }Ï
When I want to delete the unwanted item from the dynamic form I use the splice method to remove the object in the given index. This removes the correct object from the array but on the UI part, it will always remove the last item shown in the UI rather than removing the deleted object in the array.
This is my items array
const [items, setItems] = useState(quotation.items ? quotation.items : []);
Here is the form
<div className="items-container mt-2">
{items?.map((item, index) => (<div className="items">
<div className="item-close">
<div className="item-close-icon" onClick={() => closeItem(index)}>
{items.length > 1 ? <Icon as={FaTimes} color="red.500" size="1.5em" /> : ""}
</div>
</div>
<div className="card-field-two">
<div className="card-field">
<FormLabel htmlFor="item-name">Item</FormLabel>
<Input placeholder="Item" defaultValue={item.product_id.name} disabled={!isEdit} />
</div>
<div className="card-field">
<FormLabel htmlFor="item-quantity">Quantity</FormLabel>
<Input placeholder="Quantity" defaultValue={item.quantity} disabled={!isEdit} />
</div>
</div>
<div className="card-field-two">
<div className="card-field">
<FormLabel htmlFor="item-rate">Price</FormLabel>
<Input placeholder="Price" defaultValue={item.product_id.price} disabled={true} />
</div>
<div className="card-field">
<FormLabel htmlFor="hsn">HSN</FormLabel>
<Input placeholder="HSN" defaultValue={item.product_id.hsn} disabled={!isEdit} />
</div>
</div>
<div className="card-field-two">
<div className="card-field">
<FormLabel htmlFor="cgst">CGST</FormLabel>
<Input placeholder="CGST" defaultValue={item.cgst_amount} disabled={true} />
</div>
<div className="card-field">
<FormLabel htmlFor="sgst">SGST</FormLabel>
<Input placeholder="SGST" defaultValue={item.sgst_amount} disabled={true} />
</div>
</div>
<div className="card-field-two">
<div className="card-field">
<FormLabel htmlFor="igst">IGST</FormLabel>
<Input placeholder="IGST" defaultValue={item.igst_amount} disabled={true} />
</div>
<div className="card-field">
<FormLabel htmlFor="total">Total</FormLabel>
<Input placeholder="Total" defaultValue={item.total_amount} disabled={true} />
</div>
</div>
</div>))}
<button className="add-item-btn orange-btn" disabled={!isEdit} onClick={() => setItems([...items, { product_id: { name: "", price: 0, hsn: "" }, quantity: 0, cgst_amount: 0, sgst_amount: 0, igst_amount: 0, total: 0 }])}>Add Item</button>
</div>
Here is the close function to remove the items
const closeItem = (index) => {
let itemsArray = [...items];
itemsArray.splice(index, 1);
let newArray = [...itemsArray]
setItems(newArray);
}
When you don't manually provide a key to array elements, react defaults to using index as key, which may cause problems if array elements may reorder:
We don’t recommend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state. Check out Robin Pokorny’s article for an in-depth explanation on the negative impacts of using an index as a key. If you choose not to assign an explicit key to list items then React will default to using indexes as keys.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With