flutter riverpod FutureProvider将在添加.family修饰符后继续激发

gzszwxb4  于 2023-08-07  发布在  Flutter
关注(0)|答案(2)|浏览(145)

所以我有了这样的未来供应商

final additionalCostsProvider = FutureProvider.autoDispose.family<List<ExtraCost>, List<String>>((ref, cartCodes) {
  final cartAPI = ref.watch(cartAPIProvider);
  return cartAPI.getAdditionalCosts(cartCodes: cartCodes);
});

字符串
如您所见,我将cart代码(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
});

0md85ypi

0md85ypi1#

https://riverpod.dev/docs/concepts/modifiers/family/#parameter-restrictions
这是河脚修改器**.family**的官方文档。

For families to work correctly, it is critical for the parameter passed to a
provider to have a consistent hashCode and ==.

字符串
因为它是常量,你必须为它声明一个类,你可以像下面这样创建一个类,使用包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**。
希望能成功。

mbyulnm0

mbyulnm02#

为了使family正确工作,参数应该是一个原语(bool/int/double/String)、一个常量(providers)或一个覆盖==和hashCode的不可变对象。问题很可能是因为cartCodesbuild方法中,所以从build方法中取出cartCodes
试试这个:

class AdditionalCostPage extends ConsumerWidget {
  const AdditionalCostPage({key? key}) : super(key: key);

  final List<String> cartCodes = carts.map((cart) => cart.code).toList();

@override
  Widget build(context, ref) {
    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();

        },
      ),
    );
  }
}

字符串

相关问题