Problem Statement
What are best practices for using ChangeNotifier? What common mistakes should you avoid?
Explanation
Always call notifyListeners() after modifying state, not before or during modification. Place it at the end of methods that change state so listeners receive updated values. However, avoid calling notifyListeners() when state hasn't actually changed - check if the new value differs from the old value before notifying to prevent unnecessary rebuilds of dependent widgets.
Never call notifyListeners() during build, as this triggers infinite rebuild loops. Only call it in response to events, user interactions, or async operation completions. Be careful with notifyListeners() in loops or frequently called methods as excessive notifications hurt performance - batch state changes and call notifyListeners() once after all changes complete rather than after each individual change.
Dispose ChangeNotifier properly to avoid memory leaks, though Provider handles this automatically when using ChangeNotifierProvider. If creating ChangeNotifier manually, dispose it in the State's dispose method. Never access disposed ChangeNotifier instances - this causes errors. For complex state with multiple properties, consider creating focused ChangeNotifiers for different concerns rather than one giant model, following single responsibility principle.
Use private setters for properties and public methods to modify state, ensuring notifyListeners() is always called and validation can be applied. Document which methods trigger notifications. For debugging, override notifyListeners() to log when notifications occur, helping identify performance issues from excessive notifications. Testing ChangeNotifier classes is straightforward - test methods modify state correctly and verify notifyListeners() is called using mock listeners.

