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

删除Firestore预订后,如何重新渲染React Native FlatList?

问题描述

我有一个电影预订收藏列表,点击按钮可将预订记录从Firestore数据库中删除。目前点击删除按钮后,必须刷新整个应用才能看到列表变化,希望在onPress操作完成后,FlatList能自动重新渲染。

现有代码
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(bookings);
  const bookingsRef = collection(db, "booking");

  const [bookings, setBookings] = useState({});
  useEffect(() => {
    getUser();
    getBookings();
  },[])

  const getUser = async () => {
    const snap = await getDoc(docRef)
    setUser({user, ...snap.data()})
  }

  const getBookings = async () => {
     const q = query(bookingsRef, where("users","array-contains",auth.currentUser.uid));
     const unsubscribe = onSnapshot(q, (querySnapshot) => {
     const a = [];
     querySnapshot.forEach((doc) => {            
     a.push(doc.data());
  });
     setBookings(querySnapshot.docs);
    });
  }

 const deleteBooking = async(id) => {
    try {
      await deleteDoc(doc(db, 'booking', id));
    }
    catch(e) {
      console.log(e)
    }
    console.log('deleted:' + id)
  }

  return (
<View>
  <View>
    <Text>{text}</Text>
  </View>
  
  <FlatList
    data = {filteredBookings}
    numColumns = {1}

    renderItem  = {({item}) => (
      <View>
      <View>
        <Text>{item.data().movie}</Text>
        <Text>{item.data().day} - {item.data().showtime}</Text>
      </View>

      <View>
        <TouchableOpacity onPress = {() => {deleteBooking(item.id)}}>
          <Text>Delete</Text>
        </TouchableOpacity>
      </View>
      </View>
    )}
  />
      </View>
  )
}

export default WatchList
解决方案

问题出在以下几点,修改后即可实现自动刷新:

  • filteredBookings未与bookings联动:初始时filteredBookings依赖bookings,但后续bookings更新时未同步更新filteredBookings,需添加useEffect监听bookings变化。
  • bookings初始状态错误:querySnapshot.docs是数组类型,初始状态应设为[]而非{}。
  • 未清理onSnapshot监听:getBookings中创建的unsubscribe函数需在组件卸载时调用,避免内存泄漏。

修改后的完整代码:

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(() => {
    getUser();
    // 获取unsubscribe函数,组件卸载时清理监听
    const unsubscribe = getBookings();
    return () => unsubscribe();
  },[])

  // 监听bookings变化,同步更新filteredBookings
  useEffect(() => {
    setFilteredBookings(bookings);
  }, [bookings])

  const getUser = async () => {
    const snap = await getDoc(docRef);
    setUser(prev => ({...prev, ...snap.data()}));
  }

  const getBookings = () => {
     const q = query(bookingsRef, where("users","array-contains",auth.currentUser.uid));
     // 返回unsubscribe函数供清理使用
     return onSnapshot(q, (querySnapshot) => {
       setBookings(querySnapshot.docs);
     });
  }

 const deleteBooking = async(id) => {
    try {
      await deleteDoc(doc(db, 'booking', id));
    }
    catch(e) {
      console.log(e);
    }
    console.log('deleted:' + id);
  }

  return (
    <View>
      <View>
        <Text>{text}</Text>
      </View>
      
      <FlatList
        data={filteredBookings}
        numColumns={1}
        renderItem={({item}) => (
          <View>
            <View>
              <Text>{item.data().movie}</Text>
              <Text>{item.data().day} - {item.data().showtime}</Text>
            </View>
            <View>
              <TouchableOpacity onPress={() => deleteBooking(item.id)}>
                <Text>Delete</Text>
              </TouchableOpacity>
            </View>
          </View>
        )}
      />
    </View>
  )
}

export default WatchList

关键修改说明

  • 添加依赖bookings的useEffect,当Firestore数据变化触发bookings更新时,filteredBookings会同步更新,进而触发FlatList重新渲染。
  • 将bookings初始状态改为数组,匹配querySnapshot.docs的数据类型。
  • 在组件挂载的useEffect中返回unsubscribe函数,确保组件卸载时停止Firestore实时监听,避免内存泄漏。
  • 优化setUser写法为函数式更新,避免状态依赖问题。

删除操作完成后,Firestore的onSnapshot会自动检测数据变化并更新bookings,FlatList会自动重新渲染,无需手动刷新应用。

内容的提问来源于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:45:37