Riverpod 2中使用AsyncNotifierProvider.select时如何显示加载状态?
解决Riverpod 2中AsyncNotifierProvider.select保留加载状态的问题
问题根源
你原来的写法直接将原AsyncValue强制包装成AsyncValue.data,完全忽略了原有的loading/error状态——哪怕原Provider处于加载中,select返回的依然是AsyncValue.data(null),所以when只会走到data分支,显示Size:null。
正确实现方式
要同时保留状态和优化重绘,需要在select里完整传递原AsyncValue的状态,仅在data分支提取我们关心的列表长度:
final listSize = ref.watch( asyncOnlineUsersProvider.select((asyncValue) => asyncValue.map( data: (dataState) => AsyncValue.data(dataState.value.length), error: (errorState) => AsyncValue.error(errorState.error, errorState.stackTrace), loading: (_) => const AsyncValue.loading(), )), );
也可以用when写法(效果完全一致):
final listSize = ref.watch( asyncOnlineUsersProvider.select((asyncValue) => asyncValue.when( data: (users) => AsyncValue.data(users.length), error: (err, stack) => AsyncValue.error(err, stack), loading: () => const AsyncValue.loading(), )), );
效果说明
- 原Provider处于
loading状态时,select返回AsyncValue.loading(),when会触发loading分支显示加载文本 - 原Provider出现错误时,
select会完整传递错误状态,触发error分支 - 数据加载完成后,
select仅提取列表长度,且只有长度变化时才会触发组件重绘——哪怕列表内用户的其他属性变化,只要长度不变,组件就不会重新渲染
内容的提问来源于stack exchange,提问作者Doua Beri
相关产品推荐
相关产品推荐

