State Management using ValueNotifier and ValueListenableBuilder for Dashboard App
Dashboard using ValueNotifier
and ValueListenableBuilder
.
State Management by using built-in Flutter classes.
What is State Management?
State Management is not a simple topic. How do you know if you need it? Usually, once you start developing an application you will run into this issue, how do I manage the state of data, how do I access data from different parts of the app?
We have ephemeral and app state that we can use. An ephemeral state is a local state that lives in a single widget, like a single page of the application. App state can be global, app-wide state that is shared in different parts of the app.
There is no definite way to handle state management, this is something that you need to decide depending on your needs and likes. On a simple application, the default setState() can manage to refresh the page, but what if the page has many widgets/parts that need to redraw, you do not want to refresh the entire page because it will cause that janky animation. In those cases you only want to redraw each widget as needed, therefore increasing performance.
Video Tutorial
Video Tutorial: YouTube Video
Source Code: GitHub
What is covered
In this project, you are going to take a look at:
- How to use
ValueNotifier
andValueListenableBuilder
to pass data from a parent (ancestor) widget to child (descendant) widgets in the widget tree - State Management with build-in classes, no packages
The Problem:
- Dashboard app needs to chart espresso, coffee, and latte consumption
- Drawing each bar, the chart needs to refresh independently for performance
The Solution:
- Use the
ValueNotifier
andValueListenableBuilder
to allow to selectively rebuild individual widgets for performance
ValueNotifier and ValueListenableBuilder
The ValueNotifier
and ValueListenableBuilder
allow to selectively rebuild individual widgets for performance
- Create a class that extends
ValueNotifier
- Add fields to contain data defining them as
ValueNotifier
- Add methods to modify data and call the
notifyListeners()
method - Add the
ValueListenableBuilder
widget in the widget tree to rebuild widgets selectively if the data changed by individual field
class DashboardSection { ValueNotifier<int> numberOfEspresso = ValueNotifier<int>(0); ValueNotifier<int> numberOfCoffee = ValueNotifier<int>(0); ValueNotifier<int> numberOfLatte = ValueNotifier<int>(0); DashboardSection( {required this.numberOfEspresso, required this.numberOfCoffee, required this.numberOfLatte}); } class DashboardValueNotifier extends ValueNotifier<DashboardSection> { DashboardValueNotifier({required DashboardSection value}) : super(value); void addNumberOfEspresso(int numberOfEspresso) { value.numberOfEspresso.value += numberOfEspresso; notifyListeners(); } void addNumberOfCoffee(int numberOfCoffee) { value.numberOfCoffee.value += numberOfCoffee; notifyListeners(); } void addNumberOfLatte(int numberOfLatte) { value.numberOfLatte.value += numberOfLatte; notifyListeners(); } } // Child Widget ValueListenableBuilder( valueListenable: dashboardValueNotifier.value.numberOfEspresso, builder: (BuildContext context, int value, Widget? child) { debugPrint('numberOfEspresso: ${dashboardValueNotifier.value.numberOfEspresso.value}'); return MoodVerticalBarWidget( icon: Icons.coffee_maker_outlined, numberToPlot: dashboardValueNotifier.value.numberOfEspresso.value, numberToPlotMax: numberToPlotMax, title: 'Espresso', ); }, ),
How it Works
• ValueNotifier
and ValueListenableBuilder
– The ValueNotifier
and ValueListenableBuilder
allow to selectively rebuild individual widgets for performance. Use fields to contain data defining them as ValueNotifier
. Use methods to modify data and call the notifyListeners()
method. Use the ValueListenableBuilder
widget in the widget tree to rebuild widgets selectively if the data changed by individual field.