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.

希望它有效。