为何Riverpod自动生成的StateNotifier提供者不是StateNotifierProvider?
我正在使用Riverpod架构开发Flutter应用,需要用StateNotifier跟踪一个用于保存多屏表单当前页码的int值。以下是我的StateNotifier代码:
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'multi_step_controller.g.dart'; class MultiStepFormController extends StateNotifier<int> { MultiStepFormController() : super(0); void next() => state += 1; void previous() => state -= 1; void reset() => state = 0; void setIndex(int index) => state = index; }
我尝试使用Riverpod 3.0语法自动生成该类的提供者,代码如下(已执行构建生成part文件):
@Riverpod(keepAlive: true) MultiStepFormController multiStepFormController(MultiStepFormControllerRef ref) { return MultiStepFormController(); }
但读取int值时出现错误:pageController.jumpToPage(currentIndex); The argument type 'MultiStepController' can't be assigned to the parameter type 'int'.
之后我手动编写了提供者代码:
final multiStepFormControllerProvider = StateNotifierProvider<MultiStepFormController, int>((ref) { return MultiStepFormController(); });
此时代码可正常运行。我想了解为何自动生成的提供者与手动编写的效果不同,以便未来更好地使用Riverpod自动生成代码。
核心差异:Provider类型不匹配
你手动编写的是StateNotifierProvider<MultiStepFormController, int>,这类Provider会暴露StateNotifier内部的状态值(即int类型)给消费者;而你用@Riverpod注解直接返回MultiStepFormController实例时,生成的是Provider<MultiStepFormController>,它直接暴露的是StateNotifier对象本身,而非其内部的int状态。
这就导致你读取自动生成的Provider时,拿到的是控制器实例而非页码数值,自然触发类型不匹配错误。
正确生成StateNotifierProvider的写法
要让Riverpod自动生成对应StateNotifierProvider的代码,有两种规范写法:
写法一:返回StateNotifierProvider实例
@Riverpod(keepAlive: true) StateNotifierProvider<MultiStepFormController, int> multiStepFormController(MultiStepFormControllerRef ref) { return StateNotifierProvider((ref) => MultiStepFormController()); }
写法二:继承_$XXX类(更简洁的Riverpod推荐写法)
直接将控制器逻辑整合到注解类中,Riverpod会自动生成对应的StateNotifierProvider:
@Riverpod(keepAlive: true) class MultiStepFormController extends _$MultiStepFormController { @override int build() => 0; void next() => state += 1; void previous() => state -= 1; void reset() => state = 0; void setIndex(int index) => state = index; }
这种写法生成的multiStepFormControllerProvider类型为StateNotifierProvider<MultiStepFormController, int>,消费者读取时直接拿到int类型的状态值,调用方法时通过ref.read(multiStepFormControllerProvider.notifier)获取控制器实例。
使用示例对比
读取状态值(int):
final currentIndex = ref.watch(multiStepFormControllerProvider); pageController.jumpToPage(currentIndex); // 正常工作调用控制器方法:
ref.read(multiStepFormControllerProvider.notifier).next();
内容的提问来源于stack exchange,提问作者sylvain gut.

