You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:20:56