如何从FlatList传递对象至函数以删除Firestore中的预订数据
解决Firestore电影预订列表删除按钮传递对象失败问题
问题核心
点击FlatList渲染的删除按钮时,无法正确将Firestore文档对象传递给删除函数,控制台打印报错,且无法完成Firestore文档删除操作。
修复步骤
修正
filteredBookings的初始化与更新逻辑
初始时bookings是空对象,直接用它初始化filteredBookings会导致FlatList无数据。需要将filteredBookings初始化为空数组,并在bookings更新时同步更新它:const [filteredBookings, setFilteredBookings] = useState([]); useEffect(() => { setFilteredBookings(bookings); }, [bookings]);修复
deleteBooking函数的语法错误
原代码中item.data.()是语法错误,正确调用文档数据的方式是item.data(),同时要确保访问的字段存在:const deleteBooking = async (item) => { // 先验证对象传递是否成功 console.log(item.data().movie); // 执行Firestore删除操作 const bookingDocRef = doc(bookingsRef, item.id); await deleteDoc(bookingDocRef); };补充Firestore删除的必要逻辑
删除文档需要用到文档ID,querySnapshot.docs中的每个元素都包含id属性和data()方法,所以getBookings中直接保存querySnapshot.docs是正确的,不需要额外修改。
修正后的完整代码
import { useState, useEffect } from 'react'; import { View, Text, FlatList, TouchableOpacity } from 'react-native'; import { auth, db } from '../firebase'; // 确保你的Firebase配置路径正确 import { doc, getDoc, collection, query, where, onSnapshot, deleteDoc } from 'firebase/firestore'; const WatchList = () => { const uid = auth.currentUser?.uid; const docRef = doc(db, 'users', uid); const [user, setUser] = useState({}); const [watched, setWatched] = useState(true); const [text, setText] = useState('Watched movies'); const [filteredBookings, setFilteredBookings] = useState([]); const bookingsRef = collection(db, "booking"); const [bookings, setBookings] = useState([]); useEffect(() => { if (uid) { getUser(); getBookings(); } }, [uid]); // 同步更新过滤后的预订列表 useEffect(() => { setFilteredBookings(bookings); }, [bookings]); const getUser = async () => { const snap = await getDoc(docRef); setUser({ ...user, ...snap.data() }); }; const getBookings = async () => { const q = query(bookingsRef, where("users", "array-contains", uid)); const unsubscribe = onSnapshot(q, (querySnapshot) => { setBookings(querySnapshot.docs); }); // 组件卸载时取消监听 return unsubscribe; }; const deleteBooking = async (item) => { try { // 验证传递的对象 console.log("要删除的预订:", item.data().movie); // 删除Firestore文档 const bookingDocRef = doc(bookingsRef, item.id); await deleteDoc(bookingDocRef); console.log("预订删除成功"); } catch (error) { console.error("删除预订失败:", error); } }; return ( <View> <View> <Text>{text}</Text> </View> <FlatList data={filteredBookings} numColumns={1} keyExtractor={(item) => item.id} // 添加keyExtractor避免警告 renderItem={({ item }) => ( <View style={{ flexDirection: 'row', justifyContent: 'space-between', padding: 10, borderBottomWidth: 1 }}> <View> <Text>{item.data().movie}</Text> <Text>{item.data().day} - {item.data().showtime}</Text> </View> <View> <TouchableOpacity onPress={() => deleteBooking(item)}> <Text style={{ color: 'red' }}>Delete</Text> </TouchableOpacity> </View> </View> )} /> </View> ); }; export default WatchList;
额外说明
- 增加了
auth.currentUser?.uid的可选链操作,避免用户未登录时出现错误。 - 给
FlatList添加了keyExtractor,解决React Native列表渲染的key警告。 - 在
deleteBooking中添加了try-catch捕获错误,便于调试。 getBookings返回unsubscribe函数,组件卸载时会自动取消Firestore监听,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Mihailo
相关产品推荐
相关产品推荐

