I'm building a React component that shows data on an Order Summary Screen to conclude the order process for my App.
I am receiving the message:
Warning: Each child in a list should have a unique "key" prop.%s%s See...
Here is the complete error for reference:
Check the render method of `SummaryOrder`., ,
in RCTView (at SummaryOrder.js:24)
in SummaryOrder (at PreOrderScreen.js:111)
in ScrollView (at PreOrderScreen.js:105)
in RCTView (at PreOrderScreen.js:99)
Location on errors are also marked with "=>".
SummaryOrder.js:
import React from "react";
import { View, StyleSheet } from "react-native";
//Number
import NumberFormat from "../../../components/UI/NumberFormat";
//PreOrderItem
import PreOrderItem from "./PreOrderItem";
//Text
import CustomText from "../../../components/UI/CustomText";
import Colors from "../../../utils/Colors";
//PropTypes check
import PropTypes from "prop-types";
export class SummaryOrder extends React.PureComponent {
render() {
const { cartItems, total } = this.props;
return (
in RCTView (at SummaryOrder.js:24) => ***<View style={styles.container}>***
<CustomText style={{ ...styles.title, marginVertical: 5 }}>
Order Summary
</CustomText>
<View style={{ backgroundColor: "#fff", paddingHorizontal: 10 }}>
{cartItems.map((item) => {
return (
in SummaryOrder (at PreOrderScreen.js:111) => ****<View key={item.item.createdAt}>****
<PreOrderItem item={item} />
</View>
);
})}
</View>
<View style={styles.total}>
<CustomText
style={{
fontSize: 15,
color: Colors.text,
fontWeight: "500",
}}
>
Total
</CustomText>
<NumberFormat price={total.toString()} />
</View>
</View>
);
}
}
SummaryOrder.propTypes = {
cartItems: PropTypes.array.isRequired,
total: PropTypes.number.isRequired,
};
PreOrderScreen.js:
import React, { useState, useEffect, useRef } from "react";
import { useIsFocused } from "@react-navigation/native";
import { View, StyleSheet, ScrollView } from "react-native";
//Address
import Address from "./components/Address";
//Redux
import { useSelector } from "react-redux";
//Steps
import Colors from "../../utils/Colors";
import { Header, SummaryOrder, TotalButton, UserForm } from "./components";
import Loader from "../../components/Loaders/Loader";
export const PreOrderScreen = (props) => {
const unmounted = useRef(false);
const isFocused = useIsFocused();
const [loading, setLoading] = useState(true);
const carts = useSelector((state) => state.cart.cartItems);
const { cartItems, total, cartId } = props.route.params;
const [error, setError] = useState("");
const [name, setName] = useState("");
const [phone, setPhone] = useState("");
const [address, setAddress] = useState("");
const [province, setProvince] = useState("");
const [town, setTown] = useState("");
useEffect(() => {
return () => {
unmounted.current = true;
};
}, []);
useEffect(() => {
if (isFocused) {
setLoading(true);
const interval = setInterval(() => {
setLoading(false);
}, 1000);
return () => clearInterval(interval);
}
return;
}, [isFocused]);
const getInfo = (province, town) => {
setProvince(province);
setTown(town);
};
const getReceiver = (name, phone, address) => {
setName(name);
setPhone(phone);
setAddress(address);
};
const checkValidation = (error) => {
setError(error);
};
let orderItems = [];
cartItems.map((item) => {
orderItems.push({ item: item.item._id, quantity: item.quantity });
});
const fullAddress = `${address}, ${town} ,${province}`;
const toPayment = async () => {
try {
if (error == undefined && province.length !== 0 && town.length !== 0) {
props.navigation.navigate("Payment", {
screen: "PaymentScreen",
params: {
fullAddress,
orderItems,
name,
phone,
total,
cartId,
carts,
},
});
} else {
alert("Please enter your full information.");
}
} catch (err) {
throw err;
}
props.navigation.navigate("Payment", {
screen: "PaymentScreen",
params: {
fullAddress,
orderItems,
name,
phone,
total,
cartId,
carts,
},
});
};
useEffect(() => {
if (carts.items.length === 0) {
props.navigation.goBack();
}
}, [carts.items]);
return (
in RCTView (at PreOrderScreen.js:99) => ***<View style={styles.container}>***
<Header navigation={props.navigation} />
{loading ? (
<Loader />
) : (
<>
<ScrollView>
<UserForm
getReceiver={getReceiver}
checkValidation={checkValidation}
/>
<Address getInfo={getInfo} />
in ScrollView (at PreOrderScreen.js:105) =>
***<SummaryOrder cartItems={cartItems} total={total} />***
</ScrollView>
<TotalButton toPayment={toPayment} />
</>
)}
</View>
);
};
Thanks for your help in advance!