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

React Native FlatList筛选异常求助:首次加载无筛选、切换需两次点击

问题修复:观影列表切换与筛选异常

问题描述

需求:实现一个切换开关,在「待观看(To Watch)」和「已观看(Watched)」预订列表间切换。更新待观看列表中的影片后,该影片需从当前FlatList移除并出现在已观看列表,反之亦然。

当前存在的问题:

  • 首次打开页面时,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('To watch');
  const [filteredBookings, setFilteredBookings] = useState([]);

  const bookingsRef = collection(db, "booking");
  const [bookings, setBookings] = useState([]);

  useEffect(() => {
    getUser();
    getBookings();
  }, []);

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

  const getBookings = async () => {
    const q = query(bookingsRef, where("users", "array-contains", auth.currentUser.uid));
    const unsubscribe = onSnapshot(q, (querySnapshot) => {
      setBookings(querySnapshot.docs);
    });
    return unsubscribe;
  };

  const filterBookings = (currentBookings, isWatched) => {
    return currentBookings.filter(item => item.data().watched === isWatched);
  };

  const toggleSwitch = () => {
    const newWatchedState = !watched;
    setWatched(newWatchedState);
    setFilteredBookings(filterBookings(bookings, newWatchedState));
    setText(newWatchedState ? 'To watch' : 'Watched');
  };

  const updateBooking = async (id) => {
    try {
      await setDoc(doc(db, 'booking', id), {
        watched: true
      }, { merge: true });
    } catch (e) {
      console.log(e);
    }
  };

  const updateBooking1 = async (id) => {
    try {
      await setDoc(doc(db, 'booking', id), {
        watched: false
      }, { merge: true });
    } catch (e) {
      console.log(e);
    }
  };

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

  useEffect(() => {
    if (bookings.length > 0) {
      setFilteredBookings(filterBookings(bookings, watched));
    }
  }, [bookings, watched]);

  return (
    <View>
      <View>
        <Text>{text}</Text>
        <Switch
          value={watched}
          onValueChange={toggleSwitch}
        />
      </View>

      <FlatList
        data={filteredBookings}
        extraData={filteredBookings}
        keyExtractor={(item) => item.id}
        renderItem={({ item }) => (
          <View>
            <View>
              <Text>{item.data().movie}</Text>
              <Text>{item.data().day} - {item.data().showtime}</Text>
            </View>
            <View>
              {item.data().watched === true ? (
                <TouchableOpacity onPress={() => updateBooking1(item.id)}>
                  <Image source={require('../assets/watched.png')} />
                </TouchableOpacity>
              ) : (
                <TouchableOpacity onPress={() => updateBooking(item.id)}>
                  <Image source={require('../assets/towatch.png')} />
                </TouchableOpacity>
              )}

              <TouchableOpacity onPress={() => deleteBooking(item.id)}>
                <Image source={require('../assets/remove.png')} />
              </TouchableOpacity>
            </View>
          </View>
        )}
      />
    </View>
  );
};

export default WatchList;

关键修复点说明

1. 初始状态与自动筛选逻辑

  • 将bookings初始化为空数组[],避免对象类型导致的筛选错误
  • 新增filterBookings工具函数统一处理筛选逻辑
  • 监听bookings和watched的变化,自动重新筛选数据,确保首次加载和数据更新后列表正确显示

2. 切换开关逻辑修正

  • 先计算新的watched状态,再基于新状态筛选数据,避免使用旧状态导致的两次点击问题
  • 给Switch添加onValueChange={toggleSwitch}绑定切换函数,确保点击开关能触发状态更新

3. 更新/删除操作的状态同步

  • 修正按钮点击时调用的函数名(原代码错误调用了不存在的updateBookings,实际应为updateBooking/updateBooking1)
  • 移除手动清空filteredBookings的操作,依赖onSnapshot监听数据库变化自动更新bookings,进而触发筛选逻辑更新列表

4. FlatList优化

  • 添加keyExtractor属性,避免React Native渲染警告
  • 将extraData改为filteredBookings,确保数据更新时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 15:30:45