State management is a key part of building responsive and interactive Flutter apps. While there are many external packages available (such as Provider, Riverpod, and Bloc) that help in managing state, Flutter also provides an effective way to handle state without using external packages. In this article, we will focus on ChangeNotifier and ValueNotifier for flutter state management without relying on any third-party libraries.
ChangeNotifier
ChangeNotifier is a class provided by Flutter that can be used to notify listeners when there is a change in the state. It is ideal for managing simple states and notifying widgets when something changes.
When to Use ChangeNotifier
- Simple States: If your app only has basic needs like updating a widget when a button is clicked, ChangeNotifier is a perfect fit.
- Performance Consideration: It works well when you have a small number of listeners.
Example of ChangeNotifier
import 'package:flutter/material.dart';
class CounterModel extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners(); // Notify listeners when the state changes
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ChangeNotifierExample(),
);
}
}
class ChangeNotifierExample extends StatefulWidget {
@override
_ChangeNotifierExampleState createState() => _ChangeNotifierExampleState();
}
class _ChangeNotifierExampleState extends State<ChangeNotifierExample> {
final CounterModel _counterModel = CounterModel();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("ChangeNotifier Example"),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Counter Value:',
style: TextStyle(fontSize: 24),
),
AnimatedBuilder(
animation: _counterModel,
builder: (context, child) {
return Text(
_counterModel.count.toString(),
style: TextStyle(fontSize: 48),
);
},
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_counterModel.increment();
},
child: Icon(Icons.add),
),
);
}
}
In the above example, we define a CounterModel
that holds the state (the counter value) and updates it when a button is pressed. The widget listens to these changes and updates the UI accordingly using ValueListenableBuilder
.
ValueNotifier
ValueNotifier
is another simple class that is optimized for managing small states. It is a specialized implementation of ChangeNotifier
that works with a single value. It provides a more lightweight solution compared to ChangeNotifier
.
When to Use ValueNotifier
- Simple States: Just like
ChangeNotifier
,ValueNotifier
works best with simple states that revolve around a single value. - Better Performance: Since
ValueNotifier
works with a single value, it is more optimized and lightweight compared toChangeNotifier
.
Example of ValueNotifier
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ValueNotifierExample(),
);
}
}
class ValueNotifierExample extends StatelessWidget {
final ValueNotifier<int> _counter = ValueNotifier<int>(0);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("ValueNotifier Example"),
),
body: Center(
child: ValueListenableBuilder<int>(
valueListenable: _counter,
builder: (context, value, child) {
return Text(
value.toString(),
style: TextStyle(fontSize: 48),
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_counter.value += 1;
},
child: Icon(Icons.add),
),
);
}
}
In the ValueNotifierExample
, we are using ValueNotifier
to handle a simple counter state. Here, the state is represented by _counter
, and whenever the value is updated, the UI is rebuilt using ValueListenableBuilder
.
When to Choose Between ChangeNotifier and ValueNotifier
- ChangeNotifier: Useful when managing more complex states involving multiple values and notifying multiple listeners. It is still lightweight but is slightly heavier than
ValueNotifier
. - ValueNotifier: Great for very simple states where only a single value is involved and you want to optimize performance even more.
Is It Suitable for Complex States?
While both ChangeNotifier
and ValueNotifier
are great for managing simple states, they may not be the best choice for more complex state management needs. As your app grows and requires more complex interactions between widgets and states, you may need to consider more robust solutions.
Conclusion
For small to moderately complex apps, managing state with ChangeNotifier
and ValueNotifier
is more than sufficient. These built-in tools are simple to implement, lightweight, and efficient for many common use cases. However, as the complexity of your app increases, you may find that external packages that offer better scalability and organization.
Remember, for flutter state management always choose the solution that fits the complexity and performance needs of your application.