从子级更改状态时,小部件不使用Riverpod重建

问题描述

我正在使用riverpod来构建我的应用,而我正在努力构建一个简单的添加到收藏夹功能。我有一个产品列表和一个子级Consumer窗口小部件,该窗口小部件是带有“添加到收藏夹”按钮的卡片。

当我更改子卡中产品的状态时,UI不会重建。

这是git仓库https://github.com/nisa10880/riverpod_difficulties

Consumer(
    builder: (context,watch,child) =>
        watch(getProductsFutureProvider).when(
            data: (p) {
              final products = watch(productListStateProvider).state;

              return ListView.builder(
                  itemCount: products.length,itemBuilder: (BuildContext context,int index) =>
                      ProductCard(product: products[index]));
            },loading: () => CircularProgressIndicator(),error: (e,s) => Text(e)))
final productServiceProvider = Provider<ProductService>((ref) {
  return ProductService();
});

class ProductService {
  ProductService();

  Future<List<ProductModel>> getAllProducts() async {
    await Future.delayed(Duration(seconds: 1));

    return [
      ProductModel(id: '1',title: 'product 1',isFavorite: false),ProductModel(id: '2',title: 'product 2',ProductModel(id: '3',title: 'product 3',ProductModel(id: '4',title: 'product 4',isFavorite: false)
    ];
  }
}

final productListStateProvider = StateProvider<List<ProductModel>>((ref) {
  return [];
});

final getProductsFutureProvider =
    FutureProvider.autoDispose<List<ProductModel>>((ref) async {
  ref.maintainState = true;
  final evtentService = ref.watch(productServiceProvider);
  final products = await evtentService.getAllProducts();
  ref.read(productListStateProvider).state = products;

  return products;
});

class ProductCard extends ConsumerWidget {
  final ProductModel product;

  const ProductCard({
    @required this.product,Key key,}) : super(key: key);

  @override
  Widget build(BuildContext context,ScopedReader watch) {
    return Card(
        child: Column(
      children: <Widget>[
        Text(product.title),product.isFavorite
            ? IconButton(
                icon: Icon(Icons.favorite),color: Colors.red,onPressed: () {
                  product.isFavorite = !product.isFavorite;
                },)
            : IconButton(
                icon: Icon(Icons.favorite_border),color: Colors.black54,)
      ],));
  }
}

解决方法

问题是您要更新内部值ProductModel而不是状态(状态为List<ProductModel>),因此它不会触发重建,您可以尝试执行以下操作:

onPressed: () {
   List<ProductModel> productList = context.read(productListStateProvider).state;
   int index = productList.indexWhere((e) => e.id == product.id);
   productList[index].isFavorite = !product.isFavorite;
   context.read(productListStateProvider).state = productList;
},

或者您尝试使用ChangeNotifierProvider,以便在感觉到对值进行了更改时可以调用notifyListeners()

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...