Flutter中Riverpod的ref无法使用?await报错问题求解
Flutter Riverpod 代码错误排查
我在Flutter项目的ConsumerStateless组件内尝试编写如下addPayeeNew函数,使用Riverpod实现功能:
Future<FbPayee> addPayeeNew (String newPayee) async { // fetch list of payees final payeesListValue = ref.watch(payeesListFutureProvider); // [1] // check for duplicate return payeesListValue.when( data: (payees) { // if duplicate then return existing item for (FbPayee payee in payees) { if (payee.name.toLowerCase() == newPayee.toLowerCase()) { return payee; } } // else add new item and then return it FbPayee newFbPayee = FbPayee( name: newPayee, archived: false, ); FbPayee insertedPayee = await payeeRepo.insertPayeeNew(newFbPayee); // [2] return insertedPayee; }, error: (e, st) => Center(child: Text('Error! $e')), loading: () => const Center(child: CircularProgressIndicator.adaptive()), ); }
但遇到两个错误:
- 在[1]处提示“Undefined name: 'ref'”,我不理解为何未定义,Riverpod的Provider是全局的,且该函数位于ConsumerStateless组件内,应该有WidgetRef引用;
- 在[2]处提示“The await expression can only be used in an async function.”,但调用代码明明在标记为async的函数内。
错误原因及解决方法
错误1:ref未定义
ConsumerStateless组件的ref仅能在build方法的参数中直接访问,你定义的addPayeeNew是类内普通函数,没有自动获取ref的权限。解决方式:
- 将
WidgetRef作为参数传入函数:
调用时从组件的Future<FbPayee> addPayeeNew (String newPayee, WidgetRef ref) async { final payeesListValue = ref.watch(payeesListFutureProvider); // 后续逻辑不变 }build方法中传入ref即可。
错误2:await只能在async函数内使用
外层addPayeeNew是async函数,但when的data回调是同步函数,在同步回调里使用await必然报错。需要把data回调标记为async,同时调整返回类型适配:
data: (payees) async { // 检查重复逻辑不变 // ... FbPayee insertedPayee = await payeeRepo.insertPayeeNew(newFbPayee); return insertedPayee; },
另外,你的error和loading分支返回的是Widget,但函数返回类型是Future<FbPayee>,类型完全不匹配,必须修正:
error分支可抛出异常或返回默认FbPayee实例:error: (e, st) => throw Exception('Failed to load payees: $e'),- 更简洁的写法是直接await获取Future结果,避免状态不匹配:
Future<FbPayee> addPayeeNew (String newPayee, WidgetRef ref) async { // 直接await拿到payees列表,跳过when状态处理 final payees = await ref.read(payeesListFutureProvider.future); // 检查重复 for (FbPayee payee in payees) { if (payee.name.toLowerCase() == newPayee.toLowerCase()) { return payee; } } // 添加新收款人 FbPayee newFbPayee = FbPayee( name: newPayee, archived: false, ); return await payeeRepo.insertPayeeNew(newFbPayee); }
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

