Riverpod 2 Generator报错:HWFamily无法赋值给ProviderListenable参数
Riverpod 2 Generator 使用问题
背景
我按照某示例使用Riverpod 2 Generator编写代码,写出了如下代码:
@riverpod class HW extends _$HW { @override dynamic build(foo) => 'HelloWorld'; // 不添加foo时会出现错误:build dynamic Function()无法正确覆写build (dynamic Function(dynamic) }
调用时的报错
在Consumer中调用时遇到以下问题:
return Consumer(builder: (context, ref, child) { var s1 = ref.watch(hWProvider); // 报错:参数类型'HWFamily'无法分配给参数类型'ProviderListenable<dynamic>'。 var s2 = ref.watch(hWProvider.notifier); // 报错:类型'HWFamily'中未定义getter 'notifier'。 var s3 = ref.watch(hWProvider.call('foo'); // 此写法似乎可行 ...
疑问
- 是我操作有误,还是参考示例已过时?
- 若示例过时,有没有合适的替代示例参考?
foo的作用是什么?
使用版本
- flutter_riverpod: 2.1.3
- riverpod_annotation: 1.1.1
- riverpod_generator: 1.1.1
编辑补充:我怀疑是构建流程的问题。终止watch进程,删除main.g.dart文件,移除foo后重新启动watch,一切恢复正常。看起来是我为解决覆写错误添加的foo导致生成了Family。
问题解答
核心原因
你添加的foo参数触发了Riverpod的Family Provider生成逻辑。当build方法带有参数时,Riverpod Generator会自动生成Family类型的Provider(也就是HWFamily),这类Provider必须传入参数才能创建具体实例,所以直接用ref.watch(hWProvider)会报错——它现在是Family,不是普通Provider。
foo的作用
Family Provider的参数(比如这里的foo)用来区分不同的Provider实例。举个例子,如果你需要根据不同ID返回不同内容的多个"HelloWorld"状态实例,就可以通过传入不同的foo值来创建独立的状态。但如果你的业务不需要多实例区分,完全没必要加这个参数。
解决步骤
- 移除
build方法的foo参数,恢复无参写法:
@riverpod class HW extends _$HW { @override dynamic build() => 'HelloWorld'; }
- 清理并重新生成代码:终止
build_runner watch进程,删除自动生成的.g.dart文件(比如main.g.dart),再重新执行flutter pub run build_runner watch或build命令,确保生成的是普通Provider而非Family。 - 之后即可正常调用:
var s1 = ref.watch(hWProvider); // 正常获取状态 var s2 = ref.watch(hWProvider.notifier); // 正常获取notifier
关于示例过时
你遇到的问题大概率是示例过时或误解了示例中参数的用途。Riverpod 2 Generator的标准规则是:无参build对应普通Provider,带参build对应Family Provider,两者用法完全不同。
内容的提问来源于stack exchange,提问作者pinoyyid
相关产品推荐
相关产品推荐

