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

Flutter中Riverpod 2.0 NotifierProvider使用报错与状态更新求助

Riverpod 2.0 NotifierProvider 问题修复指南

一、解决Provider声明的两个错误

错误1:The getter 'new' isn't defined for the type 'dynamic'

这个错误是因为误用了旧版语法或类型推断失效导致的。Riverpod 2.0中NotifierProvider无需通过.new调用,直接使用构造函数即可,同时必须显式指定泛型参数(Notifier类型和状态数据类型),避免dynamic类型问题。

错误2:The type of 'globalProvider' can't be inferred because it depends on itself through the cycle: globalProvider

这是循环依赖引发的问题:你的GlobalsNotifier内部直接或间接引用了globalProvider(比如在构造函数、方法里调用ref.read(globalProvider)),而globalProvider又依赖GlobalsNotifier,形成闭环。解决方法是移除Notifier对自身Provider的引用,若需要访问其他状态,直接依赖对应的其他Provider即可。

二、正确更新Provider状态(以getCurrentAgencyName为例)

Riverpod的Notifier状态是不可变对象,必须通过生成新的状态实例来更新,不能直接修改原有state的属性。具体步骤:

  1. 在Globals数据类中实现copyWith方法,用于生成新的实例;
  2. 在GlobalsNotifier的方法中,调用state = state.copyWith(...)完成状态更新。

完整示例代码

1. 定义不可变的Globals数据类

class Globals {
  final String? agencyName;
  // 其他全局属性

  const Globals({this.agencyName});

  // 实现copyWith方法,用于生成新状态
  Globals copyWith({String? agencyName}) {
    return Globals(
      agencyName: agencyName ?? this.agencyName,
      // 其他属性同理处理
    );
  }
}

2. 实现GlobalsNotifier

注意:禁止在Notifier中引用自身对应的Provider

class GlobalsNotifier extends Notifier<Globals> {
  @override
  Globals build() {
    // 返回初始状态
    return const Globals();
  }

  // 更新agencyName的方法
  void getCurrentAgencyName(String newAgencyName) {
    // 通过copyWith生成新状态并赋值给state
    state = state.copyWith(agencyName: newAgencyName);
  }

  // 其他状态更新方法
}

3. 正确声明globalProvider

// 显式指定泛型参数,避免类型推断问题
final globalProvider = NotifierProvider<GlobalsNotifier, Globals>(
  () => GlobalsNotifier(),
);

状态读取与更新示例

在Widget中使用:

// 读取状态
final globals = ref.watch(globalProvider);

// 更新状态
ref.read(globalProvider.notifier).getCurrentAgencyName("新机构名称");

内容的提问来源于stack exchange,提问作者LostTexan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 02:42:49