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

无法将Firestore数据加载至React Native FlatList,求解决方案

问题原因与修复方案

你的代码存在几个关键问题,导致数据无法渲染到FlatList中,页面一直显示加载动画:

1. 错误更新exerciseList状态

在getExercise函数中,你通过forEach循环逐个更新exerciseList,但每次都将数组替换为单个对象(setExerciseList({...})),最终exerciseList变成了对象而非数组,exerciseList.length会变为undefined,因此判断条件exerciseList.length > 0始终不成立,一直显示加载动画。

修复方式:先收集所有文档数据到一个数组,再一次性更新状态:

const getExercise = async() => {
  const querySnapshot = await getDocs(collection(db, "Exercise"));
  const exercises = [];
  querySnapshot.forEach((doc) => {
    console.log(doc.id, doc.data());
    exercises.push({
      ...doc.data(),
      id: doc.id,
    });
  });
  setExerciseList(exercises);
};

2. 字段名不匹配

  • 你在添加数据时,Firestore中存储的字段是title,但在获取数据时错误地使用了doc.exerciseTitle,这会导致title字段为空;
  • FlatList的renderItem中也错误地使用了item.exerciseTitle,应该对应item.title。

3. 组件名错误

你导入的组件是Exercise,但在renderItem中使用了不存在的ExerciseItem,需要改为Exercise。

4. 练习数量显示固定值

noOfExercises的文本固定为0,应该改为显示exerciseList.length来实时反映数据数量。


完整修正后的代码

import { Pressable, Text, TextInput, View, StyleSheet, SafeAreaView, FlatList, ActivityIndicator } from 'react-native'
import React, { useState, useEffect } from 'react'
import Exercise from '../../components/Exercise'
import { MaterialIcons } from '@expo/vector-icons'; 
import { auth, app, db, getFirestore, collection, addDoc, getDocs } from '../../firebase'


const WorkoutScreen = () => {
  
  const [exerciseTitle, setTitle] = useState('');
  const [exerciseList, setExerciseList] = useState([]);

  const addExercise = async() => {
    try {
      const docRef = await addDoc(collection(db, "Exercise"), {
        title: exerciseTitle,
        isChecked: false,
      });
      console.log("Document written with ID: ", docRef.id);
      setTitle("");
      // 添加后重新获取数据,更新列表
      getExercise();
    } catch (e) {
      console.error("Error adding document: ", e);
    }
  };

  const getExercise = async() => {
    const querySnapshot = await getDocs(collection(db, "Exercise"));
    const exercises = [];
    querySnapshot.forEach((doc) => {
      console.log(doc.id, doc.data());
      exercises.push({
        ...doc.data(),
        id: doc.id,
      });
    });
    setExerciseList(exercises);
  };

  useEffect ( () => {
    getExercise();
  }, []);
  
  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.header}> 
      {/* heading */}
        <Text style={styles.heading}>Workout List</Text>
      {/* shopping items  */}
        <Text style={styles.noOfExercises}>{exerciseList.length}</Text>
      {/* delete all  */}
        <Pressable>
        <MaterialIcons name="delete" size={32} color="black" />
        </Pressable>  
      </View>
        {exerciseList.length > 0 ? (
        <FlatList
          data={exerciseList}
          renderItem ={({item}) => <Exercise title={item.title}/>}
          keyExtractor={(item) => item.id}
        />
      ) : (
        <ActivityIndicator />
      )}
        <TextInput
        placeholder='Enter Excercise' 
        style={styles.input} 
        value={exerciseTitle} 
        onChangeText={(text) => setTitle(text)} 
        onSubmitEditing={addExercise} 
        /> 
      </SafeAreaView>
  )
}

export default WorkoutScreen

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },

  header: {
    flexDirection: 'row',
    width: '90%',
    alignSelf: 'center',
    padding: 10,
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: 10,
  },

  heading: {
    fontWeight: '900',
    fontStyle: 'bold',
    fontSize: 30,
    flex: 1,
    marginTop: 20,
  },

  noOfExercises: {
    fontSize: 20,
    fontWeight: '500',
    marginRight: 20,
  },

  input: {
    backgroundColor: 'lightgrey',
    padding: 10,
    fontSize: 17,
    width: '90%',
    alignSelf: 'center',
    marginTop: 'auto',
    borderRadius: 10,

  }
})

额外优化:在addExercise函数中添加数据后调用getExercise(),确保新增数据能实时刷新显示。

内容的提问来源于stack exchange,提问作者Dan123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 01:45:30