So far, we’ve been getting a reference to our data object and then simply used it in our builder method. If this is all you are doing, you can opt to use a Consumer instead. A consumer gets your data from the Provider and unwraps it for you to use in a builder method.
Besides the ease of use, Consumers were developed for two reasons. First, you use consumers when you reach an instance when you can’t access the build context.
Second, it also provides performance optimization for, as the documentation states, more granular rebuilds.
The consumer builder method provides three arguments. First, it provides the builder context. Next, it provides the value that you need to access. Finally, it provides a child widget. This is usually a cached part of the widget tree you are passing into the Consumer, that way, you don’t have to rebuild expensive parts of the tree. You simply pass in this cached part of the tree into the constructor whereby you can access it in the builder method.
Open your project in progress or download the starter project. We’re going to change our project to use consumers. While the code itself will look slightly different the behavior will be exactly the same.
Start by opening tutorials_page.dart. In our build method, we’ll return a consumer.
First delete the state variable.
Next, wrap the column in a builder. Update it to the following:
Widget build(BuildContext context) {
return Consumer<Pillar>(
builder: (_, pillar, __) => Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Center(
child: TutorialWidget(),
),
Padding(
padding: const EdgeInsets.only(top: 24.0),
child: Text(
'Total Tutorials: ${pillar.articleCount}',
style: const TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
)
],
),
);
}
The consumer is a type of Pillar so this means the value we are getting is a Pillar object. Now when we use Consumer builder method, we are not using the context or the child widget. In this case, we provide underscores instead.
Open tutorial_widget.dart and update it to use a consumer. Wrap it in a builder. Then update it as follows:
return Consumer<Pillar>(builder: (_, pillar, __) {
return Stack(
children: [
InkWell(
onTap: () {
pillar.increaseArticleCount();
},
child: Image.asset('assets/images/${pillar.type.imageName}',
width: 110, height: 110),
),
Positioned(
bottom: 2,
child: CircleAvatar(
backgroundColor: Colors.blue,
child: Text(pillar.articleCount.toString()),
),
)
],
);
});
Build and run. Now tap the article button and works just like before. Nice job!