Aus öffentlichen Paketdaten erstellte Orientierung.
StateNotifier ist ein Dart-Paket, das ValueNotifier mit erweiterten Funktionen für die Zustandsverwaltung außerhalb des Flutter-Frameworks erweitert. Es bietet eine saubere, reaktive Möglichkeit zur Zustandsverwaltung mit eingebauter Unterstützung für asynchrone Operationen, Fehlerbehandlung und Debugging-Tools. Für den Einsatz in nicht-Flutter-Umgebungen wie Web, Desktop und Serveranwendungen konzipiert, integriert es sich gut mit Dependency Injection und fördert die Trennung von Anliegen. Durch immutable Updates und vereinfachte Abonnements bietet das Paket verbesserte Leistung und Entwicklererfahrung.
Anwendungsfälle
Anwendungszustand in nicht-Flutter-Dart-Anwendungen verwalten
Asynchrone Zustandsübergänge mit Fehlerwiederherstellung behandeln
Integration mit Abhängigkeitsinjektionssystemen
Wiederverwendbare Zustandslogik über Plattformen hinweg erstellen
Erstellen von testbaren und wartbaren Zustandsklassen
Hauptmerkmale
Erweitert ValueNotifier um zusätzliche Funktionen
Unterstützt asynchrone Zustandsaktualisierungen und Fehler
Immutable Zustandsaktualisierungen
Eingebaute Debugging-Tools
Plattformunabhängiger Entwurf
Einfache Integration mit DI-Frameworks
Geeignet für
Dart-Entwickler, die plattformübergreifende Anwendungen erstellen
Teams, die Zustandslogik über mehrere Plattformen hinweg teilen müssen
Projekte, die eine robuste Zustandsverwaltung ohne Flutter erfordern
Entwickler, die leichtgewichtige, testbare Zustandslösungen suchen
Hinweise
Nicht für den direkten Einsatz innerhalb von Flutter-Widgets vorgesehen
Benötigt manuelle Abonnementverwaltung
Am besten mit einem Dependency-Injektionssystem kombiniert
Eingeschränkte integrierte Benutzeroberfläche
Möglicherweise sind zusätzliche Boilerplate-Code für komplexe Zustandsflüsse erforderlich
Original-README
Originaler README-Schnappschuss aus dem verknüpften Quell-Repository. Aktuelle Inhalte finden Sie im Repository.
Welcome to state_notifier~
This package is a recommended solution for managing state when using Provider or Riverpod.
The purpose of StateNotifier is to be a simple solution to control state in
an immutable manner.
While ChangeNotifier is simple, through its mutable nature, it can be harder to
maintain as it grows larger.
By using immutable state, it becomes a lot simpler to:
compare previous and new state
implement an undo-redo mechanism
debug the application state
Good practices
DON'T update the state of a StateNotifier outside the notifier
While you could technically write:
classCounterextendsStateNotifier<int> {
Counter(): super(0);
}
final notifier = Counter();
notifier.state++;
That is considered an anti-pattern (and your IDE should show a warning).
Only the StateNotifier should modify its state. Instead, prefer using a method:
Why are listeners called when the new state is == to the previous state?
You may realize that a StateNotifier does not use == to verify that
the state has changed before notifying for changes.
This behavior is voluntary, for performance reasons.
The reasoning is that StateNotifier is typically used with complex objects,
which often override == to perform a deep comparison.
But performing a deep comparison can be a costly operation, especially since
it is common for the state to contain lists/maps.
Similarly, for complex states, it is rare that when calling notifier.state = newState,
the new and previous states are the same.
As such, instead of using ==, StateNotifier relies on identical to compare
objects.
This way, when using StateNotifier with simple states like int/enums, it will
correctly filter identical states. At the same time, this preserves performance
on complex states, as identical will not perform a deep object comparison.
Using custom notification filter logic
You can override the method updateShouldNotify(T old,T current) of a StateNotifier to change the default behaviour, such as for:
using == instead of identical to filter updates, for deep state comparison
always returning true to revert to older behaviors of StateNotifier
@overrideboolupdateShouldNotify(User old, User current) {
/// only update the User content changes, even if using a different instancereturn old.name != current.name && old.age != current.age;
}
Usage
Integration with Freezed
While entirely optional, it is recommended to use StateNotifier in combination
with Freezed. Freezed is a code-generation package for data-classes in Dart, which
automatically generates methods like copyWith and adds support for union-types.
A typical example would be using Freezed to handle data vs error vs loading states.
With its union-types, it can lead to a significant improvement in maintainability as
it:
ensures that your application will not enter illogical states
(such as both having a "data" and being in the "loading" state)
ensures that logic handles all possible cases. Such as forcing that the
loading/error cases be checked before trying to access the data.
The idea is that, rather than defining the data, error and loading state in a single
object like:
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:
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 LocalStorageexpect(counter.debugState, 1);
// mockito stuffverify(mockLocalStorage.writeInt('int', 1));
});
Note:LocatorMixin only works on StateNotifier. If you try to use it on other classes by using with LocatorMixin, it will not work.