I'm still wrapping my head around state-management techniques in flutter and am a bit confused about when and why to use Provider.of<X>
vs. Consumer<X>
. I understand (I think) from the documentation that when choosing between these two you would use Provider.of when we want access to the data, but you don't need the UI to change. So the following (taken from the docs) gets access to the data and updates the UI on new events:
return HumongousWidget( // ... child: AnotherMonstrousWidget(// <- This widget will rebuild on new data events // ... child: Consumer<CartModel>( builder: (context, cart, child) { return Text('Total price: ${cart.totalPrice}'); }, ), ), );
Whereas, where we only need the data on don't want to rebuild with UI, we'd use Provider.of<X>
with the listen
parameter set to false
, as below:
Provider.of<CartModel>(context, listen: false).add(item); \\Widget won't rebuild
However, listen
isn't required and so the following will run too:
Provider.of<CartModel>(context).add(item); \\listener optional
So this brings me to a few questions:
Provider.of<X>
and Consumer<X>
. Former doesn't update UI, latter does?listen
isn't set to false
will the widget be rebuilt by default or not rebuilt? What if listen
is set to true
?Provider.of
with the option to rebuild the UI at all when we have Consumer
?The Consumer does it and takes care of it. Consumer in flutter is an object in the provider library package that obtains Provider<T> from its ancestors and passes its value to builder. Actually, Consumer calls Provider. of in a new widget, and delegates its build implementation to builder.
One of the main reasons to prefer Provider over Statefulwidget s is that, using Provider , you will rebuild only the widgets that needs that value (the Consumers ) while the other will not be rebuilt. Instead when you call setState the whole build function of the widget will be called.
Consumer is an object in the Provider library that offers a simple API to interact with your provided models in the widgets themselves. In plain English, Consumer exposes instances of provided models, so you can display data and call methods on your provided model.
The best practice of using provider: Place the Provider widget at the top of the widget tree. Bellow I put a template code that can be used for one more providers at the same place, by using MultiProvider widget under Provider package.
It doesn't matter. But to explain things rapidly:
Provider.of
is the only way to obtain and listen to an object. Consumer
, Selector
, and all the *ProxyProvider calls Provider.of
to work.
Provider.of
vs Consumer
is a matter of personal preference. But there's a few arguments for both
didChangeDependencies
For your questions:
Provider.of<X>
and Consumer<X>
. Former doesn't update UI, latter does?Provider.of<X>
depends on value of listen
to trigger a new State.build
to widgets and State.didChangeDependencies
for StatefulWidget
.
Consumer<X>
always update UI, as it uses Provider.of<T>(context)
, where listen
is true
. See full source here.
listen
isn't set to false
will the widget be rebuilt by default or not rebuilt? What if listen
is set to true
?Default value is true
, means will trigger a new State.build
to widgets and State.didChangeDependencies
for StatefulWidget
. See full source here.
static T of<T>(BuildContext context, {bool listen = true})
.
Provider.of
with the option to rebuild the UI at all when we have Consumer
?Pretty much covered by Rémi Rousselet's answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With