Flutter切换导航栏时approveList数据重复填充问题求助
解决Firestore数据重复添加到数组的问题
你的问题出在全局数组每次调用获取函数时只会追加数据,且页面切换时FutureBuilder会重新触发数据请求,导致数组内容重复累加。下面是两种解决办法:
方法一:清空数组后再添加新数据
修改getRestaurantsList函数,在获取数据前先清空approveList,避免重复追加:
List<Object> approveList = []; Future getRestaurantsList() async { // 每次请求前清空数组 approveList.clear(); var collection = FirebaseFirestore.instance.collection('Restaurants').where('status', isEqualTo: "Approved"); var querySnapshots = await collection.get(); querySnapshots.docs.forEach((element) { print(element.reference); approveList.add(element.reference.id); }); }
getRequestList函数也做同样修改,在添加数据前先清空requestList。
方法二:让Future返回数据(更推荐)
这种方式不依赖全局数组,直接通过FutureBuilder接收请求返回的结果,从根源避免重复问题:
1. 修改获取数据的函数,返回数据列表
Future<List<String>> getRestaurantsList() async { var collection = FirebaseFirestore.instance.collection('Restaurants').where('status', isEqualTo: "Approved"); var querySnapshots = await collection.get(); // 直接返回提取后的ID列表 return querySnapshots.docs.map((doc) => doc.reference.id).toList(); }
getRequestList同理修改,返回对应的ID列表:
Future<List<String>> getRequestList() async { var collection = FirebaseFirestore.instance.collection('Restaurants').where('status', isEqualTo: "Pending"); // 匹配待审核状态 var querySnapshots = await collection.get(); return querySnapshots.docs.map((doc) => doc.reference.id).toList(); }
2. 修改FutureBuilder的使用方式
不再依赖全局数组,直接使用snapshot的数据:
// 以Approved页面为例 Expanded( child: FutureBuilder<List<String>>( future: getRestaurantsList(), builder: (context, snapshot) { // 处理加载状态 if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } // 处理错误状态 if (snapshot.hasError) { return Center(child: Text('加载失败')); } // 拿到返回的数据列表 var approveList = snapshot.data ?? []; return ListView.builder( itemCount: approveList.length, itemBuilder: (context, index) { return ListTile( title: ApprovedRestaurants(documentId: approveList[index], Index: index), ); }, ); }, ), )
Pending页面的FutureBuilder也做同样修改,使用getRequestList返回的数据。
额外优化:如果IndexedStack保留页面状态导致切换时重复触发Future,可以把Future初始化放到initState里,避免重复调用:
late Future<List<String>> _approvedFuture; @override void initState() { super.initState(); _approvedFuture = getRestaurantsList(); } // 后续FutureBuilder使用_approvedFuture FutureBuilder<List<String>>( future: _approvedFuture, // ...其他代码 )
内容的提问来源于stack exchange,提问作者H. M. Zaheer Asghar
相关产品推荐
相关产品推荐

