我在我的android模拟器中收到警告,说数组或迭代器中的每个子项都应该有一个唯一的“key”道具。但是,我的孩子中有一个名为key的属性,它是产品ID,每个产品应该是唯一的。有谁知道它试图说什么或如何解决这个警告?
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>
);
}
}
答案 0 :(得分:2)
您需要添加唯一键值:
{unaddedCartItems && unaddedCartItems.map((unaddedCartItem,index) =>
<CartProductItem
key={index}
product={unaddedCartItem}
onAddToCartClicked={() => addToCart(unaddedCartItem.id)}
/>
)}
应该解决问题
答案 1 :(得分:0)
来自react docs:
键帮助React识别哪些项目已更改,已添加或已添加 除去。键应该给予数组内的元素 元素稳定的身份
所以在render()
ProductCard
方法的某个地方,您正在创建一个元素数组,但是您没有为每个元素指定key
道具(应该是唯一且可预测的值)这些元素。
答案 2 :(得分:0)
我认为这里的问题是你转换为 map 一个有3个值的对象。
地图是一组 < key , value >
对。在这种情况下,您有一个对象:
key : 85961
productId : 859610
quentity : 2
所以你的警告只是说:谁是&#39;? 的