Riverpod中FutureProvider.family返回值为null持续加载问题
问题根本原因
核心问题是传入FutureProvider.family的自定义参数类I_Rem_Params没有实现正确的等值判断逻辑。
- Riverpod的family类型提供者,会将传入的参数作为缓存key,判断是否需要复用已有的提供者实例,判断逻辑依赖参数对象的
==操作符和hashCode。 - 你当前定义的
I_Rem_Params没有重写==,Dart默认的等值判断是对比两个对象的内存地址是否一致。每次Widget执行build、调用ref.watch时,都会新建一个I_Rem_Params实例,这个新实例和之前缓存对应的参数实例内存地址不同,Riverpod会判定为你需要监听一个全新的提供者,直接销毁已经拿到计算结果的旧实例,重新执行异步逻辑。 - 因此你会看到提供者内部确实执行完成、打印出结果
2,但Widget侧始终收到AsyncLoading状态、value为null,永远卡在加载组件:旧提供者刚算出结果就被销毁,新提供者又从头开始加载,形成死循环。
修复方案
二选一即可:
方案1:手动重写参数类的==和hashCode(无额外依赖)
修改I_Rem_Params类,补充等值判断逻辑:
class I_Rem_Params { final String adminID; final String companyID; final int month; I_Rem_Params( {required this.adminID, required this.companyID, required this.month}); @override bool operator ==(Object other) => identical(this, other) || other is I_Rem_Params && runtimeType == other.runtimeType && adminID == other.adminID && companyID == other.companyID && month == other.month; @override int get hashCode => Object.hash(adminID, companyID, month); }
方案2:使用Equatable自动生成等值逻辑
引入equatable依赖,让参数类继承Equatable,不需要手动写==和hashCode:
import 'package:equatable/equatable.dart'; class I_Rem_Params extends Equatable { final String adminID; final String companyID; final int month; I_Rem_Params( {required this.adminID, required this.companyID, required this.month}); @override List<Object?> get props => [adminID, companyID, month]; }
补充:如果给
I_Rem_Params加上const构造函数,且调用时都用const创建实例,也能临时解决问题,但重写等值逻辑是更通用稳妥的做法,避免后续因为遗漏const修饰符再次触发同类问题。
内容的提问来源于stack exchange,提问作者isa
相关产品推荐
相关产品推荐

