React Native Firestore统计页面:数据表格计数无法显示求助
问题:React Native Firestore数据无法在报表表格中显示
我需要制作一个报表数据表格,展示各城市相关数据的计数。目前已经获取到城市ID,且能在console.log中拿到计数数值,但无法在页面上显示。我尝试过以下方法均未解决:
- 让
GetDetails返回snap.size无效; - 使用
FlatList无效; - 通过函数调用数据无效。
相关代码:
import React, { useState, useEffect } from 'react'; import { StyleSheet, Text, View, Button, ScrollView, FlatList } from 'react-native' import firestore from '@react-native-firebase/firestore'; import { DataTable } from 'react-native-paper'; export default function TargetStaticsScreen() { const [zones, setZones] = useState([]) function GetCities() { var z = []; firestore().collection('RandomZones').orderBy('City', 'asc').get().then(zones => { setZones(zones.docs) }) } async function GetDetails({ cityid }) { let snap = await firestore().collection('RandomZones').doc(cityid).collection('targetlist').get() return (<DataTable.Cell key={cityid} numeric>{snap.size}</DataTable.Cell> ) } function RemainingDots(cityid) { firestore().collection('RandomZones').doc(cityid).collection('targetlist').where('isUsed', '==', false).get().then(snap => { return snap.size; }) } return ( <ScrollView> <Button title='getdata' onPress={() => GetCities()} /> <DataTable> <DataTable.Header> <DataTable.Title>İl</DataTable.Title> <DataTable.Title numeric>Toplam Nokta</DataTable.Title> <DataTable.Title numeric>Kalan Nokta</DataTable.Title> <DataTable.Title numeric>Aktif Nokta</DataTable.Title> <DataTable.Title numeric>Aktif Nokta Tutar</DataTable.Title> </DataTable.Header> {zones.map((x) => { return ( <DataTable.Row key={x.id}> <DataTable.Cell>{x.id}</DataTable.Cell> <GetDetails cityid={x.id} /> <DataTable.Cell numeric>{RemainingDots(x.id)}</DataTable.Cell> <DataTable.Cell numeric>111</DataTable.Cell> <DataTable.Cell numeric>111</DataTable.Cell> </DataTable.Row> ) } )} </DataTable> </ScrollView>); }
修复方案
核心问题是在组件渲染阶段直接调用异步函数获取数据——React无法处理异步返回的JSX或数值,导致页面无法正确渲染。以下是具体修复:
1. 重构数据获取逻辑,统一存入状态
不要在渲染时实时请求Firestore,而是在获取城市列表后,一次性拉取所有统计数据并存入状态:
import React, { useState } from 'react'; import { ScrollView, Button } from 'react-native' import firestore from '@react-native-firebase/firestore'; import { DataTable } from 'react-native-paper'; export default function TargetStaticsScreen() { const [cityData, setCityData] = useState([]) // 一次性获取所有城市及对应统计数据 async function GetCityData() { // 先获取城市列表 const zonesSnapshot = await firestore() .collection('RandomZones') .orderBy('City', 'asc') .get(); // 批量请求每个城市的统计数据 const cityStats = await Promise.all( zonesSnapshot.docs.map(async (cityDoc) => { // 总点数 const totalSnap = await firestore() .collection('RandomZones') .doc(cityDoc.id) .collection('targetlist') .get(); // 剩余点数 const remainingSnap = await firestore() .collection('RandomZones') .doc(cityDoc.id) .collection('targetlist') .where('isUsed', '==', false) .get(); return { id: cityDoc.id, totalPoints: totalSnap.size, remainingPoints: remainingSnap.size, activePoints: 111, // 替换为你的实际活跃点数逻辑 activeAmount: 111 // 替换为你的实际活跃金额逻辑 }; }) ); setCityData(cityStats); } return ( <ScrollView> <Button title='获取数据' onPress={GetCityData} /> <DataTable> <DataTable.Header> <DataTable.Title>城市</DataTable.Title> <DataTable.Title numeric>总点数</DataTable.Title> <DataTable.Title numeric>剩余点数</DataTable.Title> <DataTable.Title numeric>活跃点数</DataTable.Title> <DataTable.Title numeric>活跃点数金额</DataTable.Title> </DataTable.Header> {cityData.map((city) => ( <DataTable.Row key={city.id}> <DataTable.Cell>{city.id}</DataTable.Cell> <DataTable.Cell numeric>{city.totalPoints}</DataTable.Cell> <DataTable.Cell numeric>{city.remainingPoints}</DataTable.Cell> <DataTable.Cell numeric>{city.activePoints}</DataTable.Cell> <DataTable.Cell numeric>{city.activeAmount}</DataTable.Cell> </DataTable.Row> ))} </DataTable> </ScrollView> ); }
2. 原代码无效原因
GetDetails问题:React组件不能是异步函数,它返回的是Promise而非JSX元素,无法被渲染;RemainingDots问题:函数是异步的,但直接在渲染中调用时,返回的是Promise而非实际数值,页面会显示undefined;- 状态缺失:仅存储城市列表,未存储统计数据,每次渲染重复请求数据,既低效又无法处理异步结果。
3. 优化建议
- 添加加载状态,在数据获取时显示加载提示;
- 若需要实时更新,可改用Firestore的
onSnapshot监听数据变化; - 城市数量较多时,建议分页加载,避免一次性请求过多数据影响性能。
内容的提问来源于stack exchange,提问作者Sercan Eryaz
相关产品推荐
相关产品推荐

