You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 07:30:48