Difference between Change Notifier vs Value Notifier in providers?
#provider
Answer
Overview
Both
text
ChangeNotifiertext
ValueNotifiertext
ValueNotifiertext
ChangeNotifierChangeNotifier
A class that can hold multiple state fields and notify listeners when you explicitly call
text
notifyListeners()dartclass CartNotifier extends ChangeNotifier { List<CartItem> _items = []; double _total = 0.0; bool _isLoading = false; List<CartItem> get items => _items; double get total => _total; bool get isLoading => _isLoading; void addItem(CartItem item) { _items.add(item); _total += item.price; notifyListeners(); // ← Manually trigger rebuild } void removeItem(int index) { _total -= _items[index].price; _items.removeAt(index); notifyListeners(); } Future<void> loadItems() async { _isLoading = true; notifyListeners(); _items = await CartRepository.fetch(); _isLoading = false; notifyListeners(); } }
dart// Provide it ChangeNotifierProvider(create: (_) => CartNotifier()), // Consume it Consumer<CartNotifier>( builder: (context, cart, child) => Text('Items: ${cart.items.length}'), ) // Or final cart = context.watch<CartNotifier>();
ValueNotifier
A simplified
text
ChangeNotifierdart// ValueNotifier<T> — wraps a single value final counter = ValueNotifier<int>(0); final theme = ValueNotifier<ThemeMode>(ThemeMode.light); final name = ValueNotifier<String>('Alice'); // Update value — automatically notifies listeners counter.value++; // Triggers rebuild theme.value = ThemeMode.dark; // Listen counter.addListener(() { print('Counter changed: ${counter.value}'); }); // Dispose when done counter.dispose();
dart// Widget ValueListenableBuilder<int>( valueListenable: counter, builder: (context, value, child) => Text('Count: $value'), )
Key Differences
| Feature | ChangeNotifier | ValueNotifier |
|---|---|---|
| State held | Multiple fields | Single value |
| Notification | Manual text | Automatic on text |
| Complexity | Higher (full class) | Very simple |
| Extends | text | text |
| Widget | text text | text |
| Use case | Complex state (cart, auth) | Simple single value (count, toggle) |
When to Use Which
| Scenario | Use |
|---|---|
| Counter, toggle, boolean flag | text |
| Single selected value (tab, theme) | text |
| Cart with items + total + loading | text |
| Form with multiple fields | text |
| User profile with name + email + avatar | text |
Combined Example
dart// Use ValueNotifier for simple state inside ChangeNotifier class ThemeController extends ChangeNotifier { final isDark = ValueNotifier<bool>(false); void toggle() { isDark.value = !isDark.value; notifyListeners(); } }
Rule: Use
for simple single-value state. UsetextValueNotifierwhen you have complex state with multiple related fields.textChangeNotifier