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

React Native FlatList不渲染仅显示ActivityIndicator问题解决

React Native FlatList 无法渲染Firebase数据(仅显示ActivityIndicator)

问题根源

  1. 状态类型不匹配:loca初始化为数组[],但在Get函数中用setLoca赋值了单个对象,导致loca变成对象而非数组。此时loca.length为undefined,永远不满足loca.length > 0的判断,所以一直显示ActivityIndicator。
  2. 循环中重复覆盖状态:querySnapshot.forEach里每次调用setLoca都会覆盖之前的状态,最终loca只会保留最后一个文档的数据,且setState是异步操作,console.log(loca)无法打印最新状态。
  3. 组件导入缺失:home.js中使用了<Comp />但未导入comp.js组件,会导致渲染错误。
  4. 组件命名不规范:React组件名需首字母大写,否则会被当作普通HTML标签处理。

修复后的代码

home.js

// 导入Comp组件
import Comp from './comp';

export default function Second({navigation}) {
  const [loca, setLoca] = useState([]);
  // 新增加载状态,判断更严谨
  const [isLoading, setIsLoading] = useState(true);

  const Get = async () => {
    try {
      const myDoc = collection(db, 'users');
      const querySnapshot = await getDocs(myDoc);
      // 先将所有数据收集到数组
      const userList = [];
      querySnapshot.forEach(doc => {
        console.log(doc.id, ' => ', doc.data());
        userList.push({
          id: doc.id,
          fname: doc.data().fname,
        });
      });
      // 一次性更新状态
      setLoca(userList);
    } catch (error) {
      console.error('获取数据失败:', error);
    } finally {
      setIsLoading(false);
    }
  };

  const Logout = () => {
    signOut(auth)
      .then(() => {
        console.log('log out');
        navigation.navigate('Login');
      })
      .catch(error => {
        console.log(error);
      });
  };

  useEffect(() => {
    Get();
  }, []);

  const renderItemm = ({item}) => <Comp title={item.fname} />;

  return (
    <View style={styles.conn}>
      <ImageBackground source={image} resizeMode="cover" style={{flex: 1}}>
        <View style={{paddingHorizontal: 15}}>
          <View style={styles.box}>
            <View style={{justifyContent: 'space-between'}}>
              <Text>HOME</Text>
              <TouchableOpacity style={styles.box1} onPress={Logout}>
                <Text>dd</Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={styles.box1}
                onPress={() => navigation.navigate('Third')}></TouchableOpacity>
            </View>
          </View>
          {/* 用加载状态判断,替代数组长度判断 */}
          {isLoading ? (
            <ActivityIndicator />
          ) : (
            <FlatList
              data={loca}
              renderItem={renderItemm}
              keyExtractor={item => item.id}
              // 可选:空数据时显示提示
              ListEmptyComponent={<Text>暂无用户数据</Text>}
            />
          )}
        </View>
      </ImageBackground>
    </View>
  );
}

const styles = StyleSheet.create({
  conn: {
    flex: 1,
  },
  tt: {
    color: 'white',
    backgroundColor: '#4DA69B',
    fontSize: 24,
    width: 80,
    height: 80,
    borderRadius: 40,
    alignItems: 'center',
  },
  box: {
    marginTop: 10,
    flexWrap: 'wrap',
    flexDirection: 'row',
  },
  end: {
    alignItems: 'flex-end',
    marginBottom: 10,
  },
  box1: {
    width: 48,
    height: 48,
    borderRadius: 24,
    backgroundColor: '#67BE92',
    marginTop: 10,
    marginLeft: 10,
    alignItems: 'flex-end',
  },
  boxxx: {
    backgroundColor: '#f9c2ff',
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
  },
});

comp.js

// 组件名首字母大写,符合React规范
const Comp = (props) => {
  return (
    <View style={styles.conn}>
      <View style={styles.box}>
        <Text>{props.title}</Text>
      </View>
    </View>
  );
};

export default Comp;

const styles = StyleSheet.create({
  conn: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  tt: {
    color: 'white',
    backgroundColor: '#4DA69B',
    fontSize: 24,
    width: 80,
    height: 80,
    borderRadius: 40,
    alignItems: 'center',
  },
  box: {
    flex: 1,
    marginTop: 10,
    borderRadius: 10,
    width: '100%',
    height: 115,
    borderWidth: 1,
    borderColor: '#67BE92',
    backgroundColor: 'white',
    flexDirection: 'row',
    // 可选:添加内边距,避免文字贴边
    padding: 10,
  },
  end: {
    alignItems: 'flex-end',
    marginBottom: 10,
  },
  box1: {
    width: 48,
    height: 48,
    borderRadius: 24,
    backgroundColor: '#67BE92',
    marginTop: 10,
    marginLeft: 10,
  },
});

关键修复点总结

  • 先收集所有Firebase文档数据到数组,再一次性更新状态,避免重复覆盖和异步问题。
  • 用isLoading状态控制加载提示,比判断数组长度更可靠,还能处理空数据场景。
  • 修复组件命名和导入问题,符合React规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:25:24