पाठ 17 / 25
Provider and ChangeNotifier
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.
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.
त्वरित जाँच: Which call should you use inside a button's onPressed to call a method on a provided model?
- setState()
- context.watch<T>()
- context.read<T>()
- Navigator.of(context)
Answer
context.read<T>() — read fetches the object without subscribing the widget to changes.