# Provider and ChangeNotifier — Flutter

Source: https://www.skillbyai.com/en/flutter/s-provider

> Simple, widely used app state.

## Listenable models

The **provider** package wraps InheritedWidget in a friendlier API. Put state and logic in a class extending **ChangeNotifier** and call `notifyListeners()` after changes. Expose it with `ChangeNotifierProvider(create: ...)` above the widgets that need it (or `MultiProvider` for several). In `build`, `context.watch<Cart>()` reads the model and rebuilds on change; in callbacks, `context.read<Cart>()` reads without subscribing; `context.select<Cart, int>((c) => c.count)` rebuilds only when that value changes. `Consumer<Cart>` scopes rebuilds to a small part of a widget.

## A shopping cart model

ChangeNotifier exposed with provider.

```dart
class Cart extends ChangeNotifier {
  final List<Item> _items = [];
  List<Item> get items => List.unmodifiable(_items);
  int get count => _items.length;

  void add(Item item) {
    _items.add(item);
    notifyListeners();
  }
}

void main() {
  runApp(
    ChangeNotifierProvider(create: (_) => Cart(), child: const MyApp()),
  );
}

class CartBadge extends StatelessWidget {
  const CartBadge({super.key});
  @override
  Widget build(BuildContext context) {
    final count = context.select<Cart, int>((cart) => cart.count);
    return Badge(label: Text('$count'), child: const Icon(Icons.shopping_cart));
  }
}

// in a button callback
onPressed: () => context.read<Cart>().add(item),
```

## watch in build, read in callbacks

Calling context.watch inside onPressed throws or causes needless rebuilds; calling context.read in build means the widget will not update. Keep the rule simple.

**Quiz:** Which call should you use inside a button's onPressed to call a method on a provided model?

- [ ] setState()
- [ ] context.watch<T>()
- [x] context.read<T>()
- [ ] Navigator.of(context)

*Answer:* context.read<T>(). read fetches the object without subscribing the widget to changes.
