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

React Native+Firebase数据无法在移动端渲染问题求助

React Native + Firebase 购物清单数据无法渲染的解决方法

核心问题是状态更新逻辑错误,导致本该是数组的shoppingList被改成了单个对象,FlatList无法识别并渲染数据。控制台能输出是因为数据本身没问题,只是状态格式不符合组件要求。

问题定位

看getShoppingItems函数的循环逻辑:

querySnapshot.forEach((doc) => {
  console.log(doc.id, doc.data());
  setShoppingList({
    ...doc.data(),
    id: doc.id,
  });
});

每次循环都用单个文档对象覆盖shoppingList数组,最后shoppingList变成了一个对象,而FlatList的data属性必须接收数组,所以界面无法渲染出内容。

修复步骤

  1. 修正状态更新逻辑
    先把所有文档数据收集到数组里,再一次性更新状态:
const getShoppingItems = async () => {
  const querySnapshot = await getDocs(collection(db, "shopping"));
  const newShoppingList = [];
  querySnapshot.forEach((doc) => {
    console.log(doc.id, doc.data());
    newShoppingList.push({
      ...doc.data(),
      id: doc.id,
    });
  });
  setShoppingList(newShoppingList);
};
  1. 额外优化(可选但实用)
  • 添加商品后自动刷新列表:不用重新请求数据库,直接把新项加到本地状态里,提升用户体验
const addShopingItem = async () => {
  try {
    const docRef = await addDoc(collection(db, "shopping"), {
      title: title,
      isCheked: false,
    });
    console.log("Document written with ID: ", docRef.id);
    setShoppingList(prevList => [...prevList, {
      title: title,
      isCheked: false,
      id: docRef.id
    }]);
    setTitle("");
  } catch (e) {
    console.error("Error adding document: ", e);
  }
};
  • 修正拼写错误:把标题的Sghopping Items改成Shopping Items,输入框提示Enter Shoping Itms改成Enter Shopping Items
  • 修正FlatList的keyExtrator为正确的keyExtractor,避免潜在的渲染警告

修复后的完整App.js代码

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

export default function App() {
  
  const [title, setTitle] = useState("");
  const [shoppingList, setShoppingList] = useState([]);

  const addShopingItem = async () => {
    try {
      const docRef = await addDoc(collection(db, "shopping"), {
        title: title,
        isCheked: false,
      });
      console.log("Document written with ID: ", docRef.id);
      setShoppingList(prevList => [...prevList, {
        title: title,
        isCheked: false,
        id: docRef.id
      }]);
      setTitle("");
    } catch (e) {
      console.error("Error adding document: ", e);
    }
  };

  const getShoppingItems = async () => {
    const querySnapshot = await getDocs(collection(db, "shopping"));
    const newShoppingList = [];
    querySnapshot.forEach((doc) => {
      console.log(doc.id, doc.data());
      newShoppingList.push({
        ...doc.data(),
        id: doc.id,
      });
    });
    setShoppingList(newShoppingList);
  };

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

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.header}>
        <Text style={styles.heading}>Shopping Items</Text>
        <Text style={styles.noOfItems}>{shoppingList.length}</Text>
        <Pressable>
          <MaterialIcons
            style={styles.deleteIcon}
            name="delete"
            size={30}
            color="black"
          />
        </Pressable>
      </View>
      {shoppingList.length > 0 ? (
        <FlatList
          data={shoppingList}
          renderItem={({ item }) => <ShoppingItems title={item.title} />}
          keyExtractor={(item) => item.id}
        />
      ) : (
        <ActivityIndicator />
      )}

      <TextInput
        style={styles.input}
        placeholder="Enter Shopping Items"
        value={title}
        onChangeText={(text) => setTitle(text)}
        onSubmitEditing={addShopingItem}
      />
    </SafeAreaView>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 05:17:48