Problem Statement
How do ValueNotifier and ValueListenableBuilder work together? When is this pattern preferable to Provider?
Explanation
ValueNotifier holds a single value and automatically notifies listeners when the value changes through the setter. ValueListenableBuilder listens to a ValueNotifier and rebuilds its child widget whenever the value changes. This pattern is lighter weight than Provider for simple reactive state because it doesn't require context or provider setup - just create a ValueNotifier and use ValueListenableBuilder to react to changes.
ValueListenableBuilder takes the ValueNotifier, a builder function, and optional child. The builder receives context, value, and child, returning the widget tree that depends on the value. Like Consumer, the child parameter is an optimization - pass static widgets that don't need rebuilding as child, and they'll be reused across rebuilds without reconstruction.
Use this pattern for simple local state within a single widget or small widget subtree, like form field state, toggle switches, counters, or any single-value reactive state. It's perfect when you don't need Provider's dependency injection or global access, and want minimal boilerplate. For example, a theme mode toggle might use ValueNotifier<bool> for isDarkMode with ValueListenableBuilder updating UI.
Prefer ValueNotifier for simple, self-contained state; use Provider for app-wide state or when multiple widgets across different parts of the tree need access. ValueNotifier is more explicit about what triggers rebuilds since you directly reference the notifier, while Provider is more flexible for complex state management with multiple models. Combine both - use Provider for app state and ValueNotifier for local reactive values within widgets.

