Reputation: 504
I am making an E-Commerce react native app and in the CART section of the app, I want every item added in a cart with the same ID (categoryID as you can see in the console) to render only once, but in my case if I add 3 items with same id in the cart, I will see 3 different listItems of their respected items. I want my map function to show 1 list item if there are multiple items with same id with quantity getting added. My code so far is just rendering every selected product as a separate item:
renderItems() {
let items = [];
this.state.cartItems.map((item, i) => {
console.log(item)
items.push(
<ListItem
key={i}
last={this.state.cartItems.length === i + 1}
onPress={() => this.itemClicked(item)}
>
<Thumbnail square style={{ width: 100, height: 100 }} source={{ uri: item.productdetail.image }} />
<Body style={{ paddingLeft: 10 }}>
<Text style={{ fontSize: 16 }}>
{item.productdetail.name}
</Text>
<Text style={{ fontSize: 14, fontStyle: 'italic' }}>Price: {item.productdetail.price}</Text>
<Text style={{ fontSize: 14, fontStyle: 'italic' }}>Quantity: {item.quantity > 1 ? item.quantity : 1}</Text>
</Body>
<Right>
<Button style={{ marginLeft: -25 }} transparent onPress={() => this.removeItemPressed(item)}>
<Icon size={30} style={{ fontSize: 30, color: '#95a5a6' }} name='ios-remove-circle-outline' />
</Button>
</Right>
</ListItem>
);
});
return items;}
The result of console.log is as follows
This is how my cart looks like
Now as you can see the cart should display only one listItem with same product have quantity=18
Upvotes: 2
Views: 1086
Reputation: 1248
Considering you have a simple data set like this :
const rawItemsData = [
{id: 1, qty: 2},
{id: 1, qty: 3},
{id: 2, qty: 1},
{id: 1, qty: 2},
{id: 2, qty: 5},
{id: 3, qty: 6}
];
If you want to get an array with unique item ids and summed qty, you can use reduce :
const uniqueItemsData = rawItemsData.reduce((prev, item) => {
const existingItem = prev.find(({id}) => id === item.id);
if(existingItem)
existingItem.qty = existingItem.qty + item.qty;
else
prev.push(item);
return prev;
}, []); //-> [ { id: 1, qty: 7 }, { id: 2, qty: 6 }, { id: 3, qty: 6 } ];
//Then you can use your code :
uniqueItemsData.map((item, id) => {
//..
});
Upvotes: 2
Reputation: 2404
In this case, you have to make a simple control before pushing, whether the item exists or not. It's up to you to design it:
For example, you could create another list that holds the unique items. In such a page, I believe it is useful to hold the unique items, you might need related information somewhere else too. And this list shouldn't require setState because it's just for the control.
this.state.uniqueItems = [];
In each push, add the item to the uniqueItems. Do not use setState here because it will cause redundant render:
this.state.uniqueItems.push(item);
In the map function, before pushing, check if it the id exists in the unique list. You could use a simple for loop, or lodash library, or Array's find method here.
Upvotes: 0