Sparround

Provider and ChangeNotifier

Provider is a package that puts a convenient API over InheritedWidget, and it was the choice recommended in Flutter's own docs for a long time. It has three parts:

  • `ChangeNotifier` — the class holding your state; it calls notifyListeners() when something changes
  • `ChangeNotifierProvider` — puts that object into the tree and manages its lifetime (disposing it for you)
  • `Consumer` / `context.watch` / `context.read` — the ways to read it

The distinction that matters: `watch` subscribes (rebuilds on change), `read` does not (a one-off read). Inside callbacks — an onPressed, say — you always use read.

Way to readSubscribes?When to use
`context.watch<T>()`YesInside `build`, when displaying the value
`context.read<T>()`NoInside a callback calling a method (`onPressed`)
`Consumer<T>`Yes, but only its own builderWhen you want to narrow the rebuild area
`Selector<T, R>`Yes, only to the selected sliceWhen you depend on one field of a large object

Interview tip. Two mistakes come up constantly. First: using context.read in build and then wondering why the UI does not update — read does not subscribe. Second: calling context.watch inside onPressed, which creates a pointless subscription and makes Flutter complain. The rule is simple: watch in `build`, read in callbacks.

📚 Sources and documentation