Reputation: 2373
I am getting a warning in my android emulator saying that each child in an array or iterator should have a unique "key" prop. However, I have a property called key in my children and it's the product id, which should be unique per product. Does anyone know what else it is trying to say or how I can fix this warning??
setModalVisible = (visible) => {
const unaddedCartProducts = this.state.unaddedCartItems.map((unaddedCartItem) => {
return this.props.dispatch(handleLoadProduct(unaddedCartItem.productId).then((result) => {
return this.setState({unaddedCartItem: result});
}).then(() => {
this.setState({modalVisible: visible});
}))
});
}
render() {
const {isLoading, product} = this.props.products;
const {unaddedCartItems} = this.state;
console.log('this.state: ', this.state);
if (isLoading) {
return <Loader isVisible={true}/>;
}
this.numItems = product.images.length;
let imageArray = [];
let circleArray = [];
product.images.forEach((image, i) => {
console.log(image, i);
const thisImage = (
<Image
key={`image${i}`}
source={{uri: 'https://b2b.martinsmart.com/productimages/' + image}}
style={{width: deviceWidth, borderRadius: 7}}
resizeMethod={'scale'}
resizeMode={'cover'}
/>
);
imageArray.push(thisImage);
const scrollCircleVal = this.animVal.interpolate({
inputRange: [deviceWidth * (i - 1), deviceWidth * (i + 1)],
outputRange: [-8, 8],
extrapolate: 'clamp',
});
const thisCircle = (
<View
key={`circle${i}`}
style={[
styles.track,
{
width: 8,
height: 8,
marginLeft: i === 0 ? 0 : CIRCLE_SPACE,
borderRadius: 75
},
]}
>
<Animated.View
style={[
styles.circle,
{
width: 8,
height: 8,
borderRadius: 75,
transform: [
{translateX: scrollCircleVal},
],
backgroundColor: '#FFD200'
},
]}
/>
</View>
);
circleArray.push(thisCircle)
});
const listIcon = (<Icon name="list" size={30} style={styles.listIcon}/>);
const cartIcon = (<Icon name="shopping-cart" size={30} style={styles.cartIcon} />);
const questionIcon = (<Icon name="question-circle-o" size={30} style={styles.questionIcon} />);
let price = (<Text style={styles.desc}>{'Price: $' + product.price}</Text>);
let pack = (<Text style={styles.desc}>{'Pk: ' + product.pack + ' x ' + product.averageWeight + 'lb'}</Text>);
const deliveryEle = (val) => (
<View style={{flexDirection: 'row'}}>
<Text style={styles.desc}>Delivery </Text><Text style={styles.desc}>{val}</Text>
</View>
);
const rows = [[price, pack], [deliveryEle('Tue (1/30)')]];
return (
<View style={{height: '100%', backgroundColor: '#D6D6D6'}}>
<Header/>
<View style={styles.wrapper}>
<View style={{height:'100%', borderRadius: 7}}>
<View style={styles.container}>
<ScrollView style={{borderRadius: 7}}
horizontal
showsHorizontalScrollIndicator={false}
scrollEventThrottle={10}
pagingEnabled
onScroll={
Animated.event(
[{nativeEvent: {contentOffset: {x: this.animVal}}}]
)
}
>
{imageArray}
</ScrollView>
<View style={styles.listViewContainer}>
<TouchableOpacity style={styles.listView} onPress={() => Actions.pop()}>
<View style={{flex: 1, flexBasis: 22}}>{listIcon}</View>
<View style={{flex: 2, flexBasis: 57}}><Text style={{color: '#fff'}}>List View</Text></View>
</TouchableOpacity>
</View>
<View style={styles.circleContainer}>
{circleArray}
</View>
</View>
<View style={styles.productsSection}>
<Text style={styles.title}>{product.description}</Text>
<Text style={styles.desc}>{product.brand}</Text>
<Text style={styles.desc}>Item: {product.id}</Text>
<Text style={[styles.desc, {marginBottom: 15}]}>Category: {product.category}</Text>
<Table borderStyle={{borderWidth: 0}}>
<Rows data={rows}/>
</Table>
</View>
<View style={styles.bodyFooter}>
<QuantityCounter style={{width: '100%', display: 'block', marginRight: 20}} data={{productId: product.id}} />
</View>
</View>
</View>
<View style={styles.footer}>
<View style={styles.cartContainer}>
{cartIcon}
<Text style={{color: '#3A3A3A', fontSize: 14}}>18 items</Text>
</View>
<TouchableOpacity style={styles.viewCartButtonContainer} onPress={() => this.cartRedirect()}>
<Text style={{color: '#fff', fontSize: 15, marginTop: '5%'}}>View Cart</Text>
</TouchableOpacity>
</View>
<Modal
animationType="slide"
transparent={true}
visible={this.state.modalVisible}
onRequestClose={() => {
alert('Modal has been closed.');
}}>
<View style={styles.modalWrapper}>
<View style={styles.modal}>
<View style={styles.modalHeader}>
<Text style={{fontSize: 20, color: '#000', fontWeight: 'bold'}}>Recovered Items</Text>
<TouchableOpacity onPress={() => { this.setModalVisible(!this.state.modalVisible); }}>
<Text style={{color: '#000', fontWeight: 'bold'}}>CLOSE X</Text>
</TouchableOpacity>
</View>
<View style={styles.subHeader}>
{questionIcon}<Text>Did you intend to add the following items?</Text>
</View>
<View style={styles.modalBody}>
{unaddedCartItems && unaddedCartItems.map(unaddedCartItem =>
<CartProductItem
key={unaddedCartItem.id}
product={unaddedCartItem}
onAddToCartClicked={() => addToCart(unaddedCartItem.id)}
/>
)}
</View>
<View style={styles.modalFooter}>
<TouchableOpacity style={[styles.viewCartButtonContainer, {backgroundColor: '#6A6A6A'}]} onPress={() => this.addItems}>
<Text style={{color: '#fff', fontSize: 15, marginTop: '1%'}}>Abandon All</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.viewCartButtonContainer, {backgroundColor: '#5AA958'}]} onPress={() => this.placeOrder}>
<Text style={{color: '#fff', fontSize: 15, marginTop: '1%'}}>Add All</Text>
</TouchableOpacity>
</View>
</View>
</View>
</Modal>
</View>
);
}
}
Upvotes: 0
Views: 1441
Reputation: 56
I think the problem here is that you're converting to a map an Object who has 3 values.
A map is a set of < key , value >
pairs. In this case you have an object who has:
key : 85961
productId : 859610
quentity : 2
so your warning is just saying: who's the 'key'?
Upvotes: 0
Reputation: 725
You need to add a unique key value:
{unaddedCartItems && unaddedCartItems.map((unaddedCartItem,index) =>
<CartProductItem
key={index}
product={unaddedCartItem}
onAddToCartClicked={() => addToCart(unaddedCartItem.id)}
/>
)}
Thas should resolve the problem
Upvotes: 2
Reputation: 36199
From react docs:
Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity
So somewhere in render()
method of ProductCard
you are creating an array of elements but you don't specify a key
prop (which should be a unique and predictable value) for each of these elements.
Upvotes: 0