Flutter Riverpod异步Family Provider使用优化问题咨询
优化Riverpod异步Family Provider的调用方式
针对你遇到的每次调用Provider都必须传入Model的问题,这里提供两种实用的优化方案:
方案一:将Model抽离为独立Provider,让MyProvider依赖它
把Model的管理和数据请求Provider分离,这样MyProvider无需使用Family,也不用每次调用都传参数。
步骤1:定义Model的状态Provider
根据你的使用场景选择合适的Provider类型:
- 如果Model允许临时为null(后续会初始化),用
StateProvider:
final modelProvider = StateProvider<Model?>((ref) => null);
- 如果Model必须始终存在,用
StateNotifierProvider并在作用域内初始化:
final modelProvider = StateNotifierProvider<ModelNotifier, Model>((ref) { throw UnimplementedError('请在对应作用域内初始化ModelNotifier'); }); class ModelNotifier extends StateNotifier<Model> { ModelNotifier(super.state); }
步骤2:修改MyProvider依赖该Model Provider
@riverpod class MyProvider extends _$MyProvider { @override FutureOr<MyModel> build() { final model = ref.watch(modelProvider); // 确保Model已初始化,避免假值 if (model == null) { throw StateError('Model必须先完成初始化'); } return getAllModel(model); } }
使用方式
- 对于
StateProvider:在使用MyProvider前,先通过ref.read(modelProvider.notifier).state = yourTargetModel;设置Model。 - 对于
StateNotifierProvider:在页面或组件的ProviderScope中覆盖初始化:
ProviderScope( overrides: [ modelProvider.overrideWith((ref) => ModelNotifier(yourInitialModel)), ], child: YourPage(), )
之后读取MyProvider时,直接调用ref.watch(myProviderProvider)即可,无需传参。
方案二:保留Family但启用缓存减少重复请求
如果你的业务场景确实需要动态传入不同Model,但不想重复请求相同Model的数据,可以给Family Provider启用缓存:
@riverpod class MyProvider extends _$MyProvider { @override FutureOr<MyModel> build(Model model) { // 启用缓存,相同Model的实例会被保留,不会重复执行getAllModel ref.keepAlive(); return getAllModel(model); } }
这种方式仍需传入Model,但相同Model只会发起一次请求,适合Model频繁复用的场景。
推荐优先使用方案一,它能彻底解决每次传参的问题,同时避免给MyModel设置假值,代码结构也更清晰。
内容的提问来源于stack exchange,提问作者Cyrus the Great
相关产品推荐
相关产品推荐

