Riverpod 2.0迁移:带@riverpod注解类的build()方法作用与时机
Riverpod 2.0中AsyncNotifier的build()方法:作用与使用时机
核心作用
build()是AsyncNotifier的初始化入口,它的唯一职责是返回Provider的初始状态值——代码生成器已经帮你创建了Provider实例,你不需要在build()里手动创建Provider。返回的值会被自动包装成AsyncValue类型(比如返回null就对应AsyncValue.data(null),返回Future则会先进入loading状态,直到Future完成)。
触发时机
- 首次访问Provider时:当你的UI第一次通过
ref.watch(provider)或ref.read(provider)获取这个Provider的状态时,build()会被调用一次,完成初始状态的初始化。 - 依赖的Provider更新时:如果
build()内部使用了ref.watch(otherProvider)监听其他Provider,当otherProvider的状态发生变化时,build()会重新执行,更新当前Notifier的初始状态(注意:后续你可以通过state =手动修改状态,build()的返回值只是初始值)。
结合你的场景优化
你现在返回null并手动调用asyncMethod是可行的,但如果你的异步方法是用来加载初始数据的,更合理的做法是把初始化逻辑放在build()里:
@riverpod class MyDataNotifier extends _$MyDataNotifier { @override FutureOr<MyData?> build() async { // 首次访问Provider时自动加载初始数据 return await _fetchInitialData(); } Future<void> asyncMethod() async { state = const AsyncValue.loading(); try { final newData = await _fetchUpdatedData(); state = AsyncValue.data(newData); } catch (e) { state = AsyncValue.error(e, StackTrace.current); } } // 内部封装的异步数据请求 Future<MyData?> _fetchInitialData() async { // 初始数据请求逻辑 } Future<MyData> _fetchUpdatedData() async { // 更新数据请求逻辑 } }
这样UI可以直接通过ref.watch(myDataNotifierProvider)监听状态的loading/data/error变化,无需手动触发初始化方法。
注意事项
build()只能用于初始化状态,不要在这里处理导航、弹窗等副作用,这类操作应该放在Notifier的方法中,或者通过ref.listen实现。build()支持同步返回值或FutureOr类型,AsyncNotifier会自动处理状态的包装逻辑。
内容的提问来源于stack exchange,提问作者metinbeycigim
相关产品推荐
相关产品推荐

