riverpod FutureProvider 将在添加 .family 修饰符后继续触发
riverpod FutureProvider will keep firing after adding .family modifier
所以我有这样的未来供应商
final additionalCostsProvider = FutureProvider.autoDispose.family<List<ExtraCost>, List<String>>((ref, cartCodes) {
final cartAPI = ref.watch(cartAPIProvider);
return cartAPI.getAdditionalCosts(cartCodes: cartCodes);
});
如您所见,我将购物车代码 ( List<String>
) 作为 FutureProvider
的参数
然后我就这样使用它
@override
Widget build(context, ref) {
final List<String> cartCodes = carts.map((cart) => cart.code).toList();
final additionalCostsProviderAsynValue = ref.watch(additionalCostsProvider(cartCodes));
return Scaffold(
body: additionalCostsProviderAsynValue.when(
loading: () => CircularProgressIndicator(),
error: (error, stackTrace) {
return ErrorDisplay(
onButtonClicked: () => ref.refresh(additionalCostsProvider(cartCodes)),
);
},
data: (results) {
return Container();
},
),
);
}
然后它会一遍又一遍地向服务器发出我的应用程序请求。
我认为问题出在 .family
修饰符上。因为如果改变 FutureProvider
而不是像下面的代码那样使用 .family
,问题就不会发生。
final additionalCostsProvider = FutureProvider.autoDispose<List<ExtraCost>>((ref) {
final cartAPI = ref.watch(cartAPIProvider);
return cartAPI.getAdditionalCosts(cartCodes: ["BA3131"]); // <--- if I hardcode it in here, the problem will not occurred
});
https://riverpod.dev/docs/concepts/modifiers/family/#parameter-restrictions
这是Riverpod修改器的官方文档.family.
For families to work correctly, it is critical for the parameter passed to a
provider to have a consistent hashCode and ==.
因为它是常量,你必须为它声明一个class,你可以创建一个像下面这样的class,使用包Equatable。
class ExtraCostParameter extends Equatable {
final List<String> cartCodesList;
const ExtraCostParameter({required this.cartCodesList});
@override
List<Object?> get props => [cartCodesList];
}
您未来的新提供商将如下所示。
final additionalCostsProvider = FutureProvider.autoDispose.family<List<ExtraCost>, ExtraCostParameter>((ref, param) {
final cartAPI = ref.watch(cartAPIProvider);
return cartAPI.getAdditionalCosts(cartCodes: param.cartCodesList);
});
另一方面,如果您的 List<String>
不是常数,您可能需要使用 .autoDispose.
希望它有效。
所以我有这样的未来供应商
final additionalCostsProvider = FutureProvider.autoDispose.family<List<ExtraCost>, List<String>>((ref, cartCodes) {
final cartAPI = ref.watch(cartAPIProvider);
return cartAPI.getAdditionalCosts(cartCodes: cartCodes);
});
如您所见,我将购物车代码 ( List<String>
) 作为 FutureProvider
然后我就这样使用它
@override
Widget build(context, ref) {
final List<String> cartCodes = carts.map((cart) => cart.code).toList();
final additionalCostsProviderAsynValue = ref.watch(additionalCostsProvider(cartCodes));
return Scaffold(
body: additionalCostsProviderAsynValue.when(
loading: () => CircularProgressIndicator(),
error: (error, stackTrace) {
return ErrorDisplay(
onButtonClicked: () => ref.refresh(additionalCostsProvider(cartCodes)),
);
},
data: (results) {
return Container();
},
),
);
}
然后它会一遍又一遍地向服务器发出我的应用程序请求。
我认为问题出在 .family
修饰符上。因为如果改变 FutureProvider
而不是像下面的代码那样使用 .family
,问题就不会发生。
final additionalCostsProvider = FutureProvider.autoDispose<List<ExtraCost>>((ref) {
final cartAPI = ref.watch(cartAPIProvider);
return cartAPI.getAdditionalCosts(cartCodes: ["BA3131"]); // <--- if I hardcode it in here, the problem will not occurred
});
https://riverpod.dev/docs/concepts/modifiers/family/#parameter-restrictions
这是Riverpod修改器的官方文档.family.
For families to work correctly, it is critical for the parameter passed to a
provider to have a consistent hashCode and ==.
因为它是常量,你必须为它声明一个class,你可以创建一个像下面这样的class,使用包Equatable。
class ExtraCostParameter extends Equatable {
final List<String> cartCodesList;
const ExtraCostParameter({required this.cartCodesList});
@override
List<Object?> get props => [cartCodesList];
}
您未来的新提供商将如下所示。
final additionalCostsProvider = FutureProvider.autoDispose.family<List<ExtraCost>, ExtraCostParameter>((ref, param) {
final cartAPI = ref.watch(cartAPIProvider);
return cartAPI.getAdditionalCosts(cartCodes: param.cartCodesList);
});
另一方面,如果您的 List<String>
不是常数,您可能需要使用 .autoDispose.
希望它有效。