Viewing version 0.4.0. Open the latest package page.
state_notifier
0.4.0ValueNotifier, but outside Flutter and with some extra perks
Readme
pub package Welcome to state_notifier~
This repository is a set of packages that reimplements ValueNotifier outside of Flutter.
It is spread across two packages:
state_notifier, a pure Dart package containing the reimplementation of ValueNotifier.
It comes with extra utilities for combining our "ValueNotifier" with provider and to test it.flutter_notifier, a binding betweenstate_notifierand Flutter.
It adds things like ChangeNotifierProvider from provider, but compatible withstate_notifier.
Motivation
Extracting ValueNotifier outside of Flutter in a separate package has two purposes:
- It allows packages Dart packages with no dependency on Flutter to use these
classes.
This means that we can use them on AngularDart for example. - It allows solving some common problems with the original ChangeNotifier/ValueNotifier and/or their combination with provider.
For example, by using state_notifier instead of the original ValueNotifier, then
you get:
- A significant simplification of the integration with provider
- Simplified testing/mocking
- Improved performances on
addListener¬ifyListenersequivalents. - Extra safety through small API changes
Integration with provider/service locators
StateNotifier is easily compatible with provider through an extra mixin: LocatorMixin.
Consider a typical StateNotifier written like a ValueNotifier:
class Counter extends StateNotifier<int> {
Counter(): super(0)
void increment() {
state++;
}
}
In this example, we may want to use Provider.of/context.read to connect our
Counter with external services.
To do so, simply mix-in LocatorMixin as such:
class Counter extends StateNotifier<int> with LocatorMixin {
// unchanged
}
This then gives you access to:
read, a function to obtain servicesupdate, a new life-cycle that can be used to listen to changes on a service
We could use them to change our Counter incrementation to save the counter in
a DB when incrementing the value:
class Counter extends StateNotifier<int> {
Counter(): super(0)
void increment() {
state++;
read<LocalStorage>().writeInt('count', state);
}
}
Testing
When using LocatorMixin, you may want to mock a dependency for your tests.
Of course, we still don't want to depend on Flutter/provider to do such a thing.
Similarly, since state is protected, tests need a simple way to read the state.
As such, LocatorMixin also adds extra utilities to help you with this scenario:
myStateNotifier.debugMockDependency<MyDependency>(myDependency);
print(myStateNotifier.debugState);
myStateNotifier.debugUpdate();
As such, if we want to test our previous Counter, we could mock LocalStorage
this way:
test('increment and saves to local storage', () {
final mockLocalStorage = MockLocalStorage();
final counter = Counter()
..debugMockDependency<LocalStorage>(mockLocalStorage);
expect(counter.debugState, 0);
counter.increment(); // works fine since we mocked the LocalStorage
expect(counter.debugState, 1);
// mockito stuff
verify(mockLocalStorage.writeInt('int', 1));
});
Differences with ValueNotifier
This is not a one-to-one reimplementation of ValueNotifier. It has some differences:
- ValueNotifier is instead named StateNotifier (to avoid name clash)
ValueNotifier.valueis renamed tostate, to match the class name- StateNotifier is abstract
stateis@protected- The listener passed to
addListenerreceives the currentstate, and is called synchronously on addition. addListenerandremoveListenerare fused in a singleaddListenerfunction which returns a function to remove the listener.
This makes adding and removing listeners O(1) versus O(N) for ValueNotifier.- listeners cannot add extra listeners.
This makes notifying listeners O(N) versus O(N²) for ValueNotifier - offers a
mountedboolean to know if the StateNotifier was disposed or not, similar toState.
Changelog
[0.4.0] - 13/03/2020
Added a flag on addListener to disable the first immediate call of the listener
thanks to @smiLLe
[0.3.0] - 08/03/2020
Add an initState life-cycle to be able to init the StateNotifier using read.
[0.1.0+1] - 06/03/2020
Add example
[0.1.0] - 06/03/2020
Initial release.
Installing
export PUB_HOSTED_URL=https://pub.mirror.p-hatan.ir
flutter pub add 'state_notifier:0.4.0'pubspec.yaml
name: state_notifier
description: ValueNotifier, but outside Flutter and with some extra perks
version: 0.4.0
author: Remi Rousselet <darky12s@gmail.com>
homepage: https://github.com/rrousselGit/state_notifier
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
meta: ^1.1.8
dev_dependencies:
test: ^1.12.0
mockito: ^4.1.1
matcher: ^0.12.6Version history
| Version | Published | Archive | SHA-256 |
|---|---|---|---|
| 0.1.0 | Cached · Upstream SHA-256 matched | Download | 8c60803f…6789b4 |
| 0.1.0+1 | Cached · Upstream SHA-256 matched | Download | 1ed2b17b…c3c33a |
| 0.3.0 | Cached · Upstream SHA-256 matched | Download | d4cfb50d…d92353 |
| 0.4.0 | Cached · Upstream SHA-256 matched | Download | 0834beac…80ff69 |
| 0.5.0 | Cached · Upstream SHA-256 matched | Download | 70c638d9…239200 |
| 0.6.0 | Cached · Upstream SHA-256 matched | Download | 2cf1a0b8…105e39 |
| 0.7.0-nullsafety.0 | Cached · Upstream SHA-256 matched | Download | 0615c755…7224db |
| 0.7.0 | Cached · Upstream SHA-256 matched | Download | 629c1053…e9054a |
| 0.7.1 | Cached · Upstream SHA-256 matched | Download | 46d90938…e507bf |
| 0.7.2 | Cached · Upstream SHA-256 matched | Download | bb2227ae…18bc0c |
| 0.7.2+1 | Cached · Upstream SHA-256 matched | Download | 8fe42610…aed289 |
| 1.0.0 | Cached · Upstream SHA-256 matched | Download | b8677376…ba29bb |
Dependencies
meta "^1.1.8"