what is the reason for using Provider (in a simple app) on top of global variables defined in the main file?
calling Provider has to be embedded in Build methods, so can be a direct access to global varialbes prvided the main is imported
are the widgets calling Provider somehow automatically marked for rebuild if variables are changed?
until now I am using both Provider and direct access to learn the differences
2
Answers
Yes! Although maybe not exactly how you think it works.
provider
is built in a very similar manner to howInheritedWidget
is built in the framework. When you call itsof
method (orcontext.watch
), what you really do is calldependOnInheritedWidgetOfExactType
on theBuildContext
of your widget (which context you pass to it). This registers the element of that widget to be rebuilt whenever the dependency (the providing widget) changes callingdidChangeDependencies
and then thebuild
.If you provide an ordinary class, it won’t get changed unless you use a
Provider.value
and changed the object returned invalue
. If you provide aChangeNotifier
withChangeNotifierProvider
, it will change whenever anotifyListeners
on it was called, etc.Shall you use a raw
InheritedWidget
, you would have control over when the dependents (widgets that callProvider.of
) shall get updated with aupdateShouldNotify
boolean getter.While using
provider
/InheritedWidget
you can wrap you widget tree with a newProvider
/InheritedWidget
to change the instance that will be provided down the tree. It can also handle disposing the values when the provider is removed from the tree. With global variables, you’d have to do that manually. Also in widget tests you’d have to set and clean the global variable yourself. To have multiple instances of the same class instantiated for different widget trees you can simply use a fewProvider
s, and with global variables you’d need to create a new variable.Please read the below thoroughly to better understand how these work inside:
A global in Dart is not "observable". You can locate the variable, and obtain its current value, but there’s no place to register to be informed of changes. This is particularly important if you are including the data as part of a view, or as part of data that is further observed.
The various state management solutions (including Provider, and my preferred system, Riverpod) are all mechanisms to implement "observable data", which provides three key features: locatability, current value, and registration of ongoing notifications.
Riverpod in addition has the ability to "override" the locatability, which comes in handy for testing or dependency injection.