notifier_plus is a high-performance Flutter state management library designed to optimize Listenable
updates.
Created by tachibana-shin, this library eliminates unnecessary UI rebuilds caused by ValueNotifier
and Listenable.merge
.
- Why notifier_plus?
- Installation
- Core Classes
- Watch Widgets
- Utilities
- Comparison Table
- Contributing
- License
-
ValueNotifier
causes redundant UI rebuilds when updated consecutively:a.value++; a.value++; // Causes two rebuilds, but only one is needed
-
Listenable.merge
invokes multiple rebuilds when multiple dependencies update:a.value++; b.value++; // Triggers two rebuilds instead of one
- Batches multiple updates within the same frame to trigger only one rebuild.
- Efficient state management that reduces unnecessary UI updates.
- Easy to use with
ValueNotifier
-like API but optimized for performance.
Add to pubspec.yaml
:
dependencies:
notifier_plus:
git:
url: https://github.com/tachibana-shin/notifier_plus.git
Import it:
import 'package:notifier_plus/notifier_plus.dart';
A ChangeNotifier
implementation that ensures updates are only triggered once per frame.
final counter = Notifier<int>(0);
counter.addListener(() {
print("Counter updated: ${counter.value}");
});
counter.value++; // Only one listener call per frame
✅ Features:
- Prevents redundant updates.
- Implements
ValueListenable<T>
for seamless integration.
Computes a value based on other Notifier
dependencies.
final a = Notifier<int>(1);
final b = Notifier<int>(2);
final sum = ComputedNotifier(() => a.value + b.value, depends: [a, b]);
sum.addListener(() {
print("Sum updated: ${sum.value}");
});
✅ Features:
- Automatically tracks dependencies.
- Only updates when dependent values change.
Handles derived state that depends on asynchronous computations.
final asyncSum = ComputedAsyncNotifier<int>(
() async => await fetchData(),
depends: [a, b]
);
✅ Features:
- Supports async state calculations.
- Notifies listeners only when computation completes.
Efficient UI rebuilding for state changes.
WatchComputed<int>(
computed: sum,
builder: (context, value) {
return Text("Sum: $value");
},
);
WatchAsyncComputed<int>(
computed: asyncSum,
builder: (context, value) {
return value == null ? CircularProgressIndicator() : Text("Sum: $value");
},
);
WatchComputes<int>(
computes: [a, b],
builder: (context) {
return Text("A: ${a.value}, B: ${b.value}");
},
);
WatchNotifier(
depends: [a, b],
builder: (context) {
return Text("State changed: A=${a.value}, B=${b.value}");
},
);
A helper function to debounce state updates within the same frame.
final debouncedUpdate = oneCallTask(() {
print("Updated!");
});
debouncedUpdate(); // Calls once per frame
Registers a callback that listens to multiple Listenable
s efficiently.
watch([a, b], () {
print("A or B changed");
});
Feature | notifier_plus |
---|---|
Prevents redundant UI rebuilds | ✅ |
Optimized ValueNotifier replacement |
✅ |
Efficient dependency tracking | ✅ |
Supports async computed values | ✅ |
Lightweight & easy to use | ✅ |
Pull requests are welcome! Feel free to submit issues or feature requests.
MIT License. See LICENSE for details.