在ConsumerStatefulWidget中使用FutureBuilder报错,如何修复?
错误分析与修复方案
核心错误点
1. FutureBuilder泛型语法错误
你写的FutureBuilder < Map<String, dynamic>( 完全不符合Dart泛型语法规范,且泛型类型选择错误:Firestore的collection.get()返回的是Future<QuerySnapshot>,而非单个Map<String, dynamic>,正确的泛型声明应为FutureBuilder<QuerySnapshot>(...)。
2. FutureBuilder的builder参数不符合要求
builder必须是接收BuildContext和AsyncSnapshot的回调函数,你直接用isLoaded ? ... : ...的写法完全错误,导致编译器无法识别future:和builder:这两个必填参数,进而提示它们未定义。
3. 无限循环的状态更新
你重写了setState方法并在其中调用_getTrxnData(),而_getTrxnData()内部又调用setState(),这会触发无限状态更新循环,严重影响性能。同时FutureBuilder本身可处理异步数据的加载状态,无需额外维护isLoaded和itemsTrxn这类状态变量。
修复后的完整代码
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:intl/intl.dart'; class CompanyDashboardScreen extends ConsumerStatefulWidget { static const String id = 'user_dashboard_screen'; const CompanyDashboardScreen({super.key}); @override ConsumerState<CompanyDashboardScreen> createState() => _CompanyDashboardScreenState(); } class _CompanyDashboardScreenState extends ConsumerState<CompanyDashboardScreen> { bool showSpinner = false; // 获取Firestore数据的方法,直接返回QuerySnapshot交给FutureBuilder处理 Future<QuerySnapshot> _getTrxnData() async { return FirebaseFirestore.instance .collection('company') .doc(ref.read(globalsNotifierProvider).companyId) .collection('trxns') .get(); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: CustomAppBar(), drawer: Drawer( child: ListView( children: <Widget>[ ListTile( title: const Text("User Profile"), onTap: () { MainScreen.of(context)?.setIndex(3); Navigator.of(context).push(MaterialPageRoute( builder: (context) => const UserProfileScreen())); }, ), ], ), ), body: SafeArea( child: FutureBuilder<QuerySnapshot>( future: _getTrxnData(), builder: (context, snapshot) { // 处理加载中状态 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 处理加载错误状态 if (snapshot.hasError) { return Text('加载失败: ${snapshot.error}'); } // 获取文档列表,为空时提示无数据 final trxnDocs = snapshot.data?.docs ?? []; if (trxnDocs.isEmpty) { return const Text('没有数据'); } // 构建列表 return ListView.builder( itemCount: trxnDocs.length, itemBuilder: (context, index) { final trxnData = trxnDocs[index].data() as Map<String, dynamic>; return Padding( padding: const EdgeInsets.all(8.0), child: ListTile( isThreeLine: true, title: Row( children: [ Text( 'Client: ${trxnData['clientFName'] ?? 'n/a'} ${trxnData['clientLName'] ?? 'n/a'}', style: const TextStyle( fontWeight: FontWeight.w900, color: Colors.blueAccent), ), ], ), subtitle: Text.rich( TextSpan( text: '${trxnData['propertyAddress'] ?? 'n/a'}, ' '${trxnData['propertyCity'] ?? 'n/a'}, ' '${trxnData['propertyState'] ?? 'n/a'}', children: <TextSpan>[ TextSpan( text: '\nPrice: ${trxnData['contractPrice'] == null ? 'n/a' : NumberFormat.simpleCurrency().format(trxnData['contractPrice'])}\nStatus: ${trxnData['trxnStatus'] ?? 'n/a'}', style: const TextStyle( fontWeight: FontWeight.w900, color: Colors.blueGrey), ) ], ), ), trailing: Text( 'MLS#: ${trxnData['mlsNumber'] ?? 'n/a'}\n${trxnData['clientType']}'), onTap: () { ref .read(globalsNotifierProvider.notifier) .updatenewTrxn(false); ref .read(globalsNotifierProvider.notifier) .updatecurrentTrxnId(trxnData['trxnId']); Navigator.of(context).push(MaterialPageRoute( builder: (context) => TransactionDetailScreen(trxnData['trxnId']))); }, ), ); }, ); }, ), ), ), ); } }
额外修复细节
- 修正拼写错误:
cont EdgeInsets→const EdgeInsets,No Date→No Data - 移除不必要的状态变量,直接通过FutureBuilder的snapshot获取数据
- 添加异步状态处理(加载中、错误状态),提升用户体验
- 简化Firestore数据获取逻辑,直接将异步任务交给FutureBuilder管理
内容的提问来源于stack exchange,提问作者LostTexan
相关产品推荐
相关产品推荐

