Виджет не перестраивается с помощью riverpod при изменении состояния с дочернего

Я использую riverpod для создания своего приложения, и я изо всех сил пытаюсь создать простое добавление к любимой функции. У меня есть список продуктов и дочерний потребительский виджет, который представляет собой карточку с кнопкой добавления в избранное.

Когда я изменяю состояние продуктов из дочерних карточек, пользовательский интерфейс не перестраивается.

вот репозиторий git https://github.com/nisa10880/riverpod_difficulty

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', isFavorite: false),
      ProductModel(id: '3', title: 'product 3', isFavorite: false),
      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,
                onPressed: () {
                  product.isFavorite = !product.isFavorite;
                },
              )
      ],
    ));
  }
}

person Nidhal    schedule 30.10.2020    source источник


Ответы (1)


Проблема в том, что вы обновляете внутреннее значение 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 (), когда чувствуете, что внесли изменение в значение

person EdwynZN    schedule 30.10.2020