First of all the goal is to display cars from a database on a React website, sounds simple enough, right?
I have a Firestore database that has cars in it, it looks like this:
I also have a useState hook that looks like this:
type car = {
carId: string;
model: string;
image: string;
};
const [cars, setCars]: [Array<car>, any] = React.useState([]); // update
I am getting data from the Firestore database and all is going well, except that cars from the database get added to the cars hook even though I am checking if it already exists:
React.useEffect(() => {
// Get cars from firestore database and set them with setCars
(async () => {
const querySnapshot = await getDocs(collection(db, "cars"));
querySnapshot.forEach((doc) => {
// Check if car is already in the array
for (let i = 0; i < cars.length; i ) {
if (cars[i].carId === doc.data().carId) {
console.log("Car already in array");
return;
}
}
console.table(doc.data());
setCars((cars: any) => [...cars, doc.data()]);
});
})();
}, []);
In the end cars
useState will still end up looking like this:
Any help/tips much appreciated!
CodePudding user response:
You can try the following way to check if the element already exists and see if the problem still persists.
const documentData = doc.data();
const newArray = cars.filter(const car => car.carId === documentData.carId)
if(newArray.length > 0) return;
setCars(previousCars => [...previousCars, documentData]);
CodePudding user response:
The return
inside your if
condition breaks from the immediate for
loop, meaning when it compares the first record, it matches and since item exists, that for loop breaks and the program continues on to add the car data.
What you want instead, is to simply check if the new doc.data() exists in your cars list, which you could do by:
querySnapshot.forEach((doc) => {
// Check if car is already in the array
if(!cars.find(carItem => carItem.carId === doc.data().carId){
console.table(doc.data());
setCars((cars: any) => [...cars, doc.data()]);
}
});