State management
vanilla state management - pouziti nastroju, ktere dodava ciste framework bez pouziti reseni tretich stran
- ephemeral state - docasny stav, ktery neprezije restart aplikace, byva lokalni k danemu widgetu, nikam se neuklada
- application state - stav trvalejsiho razu, pres vice screen nebo widgetu, muze se ulozit a obnovit po restartu aplikace
Lifting up
- komponenty musi sdilet nejaky stav/data (vice widgetu nebo screen)
- je mozne instanci stavu presunout do state objektu jejich sdileneho parenta
- vysledkem byva tesna zavislost (coupling) se spoustou vzajemnych callbacku predanych v konstruktoru widgetu
- neda se moc dobre skalovat a pridavanim novych podminek vznika silene komplikovany chaos
Observer pattern
- behavioralni pattern, klient se nechce cyklicky dotazovat, jestli uz nastal kyzeny stav, tak samo server(observable) nechce rozesilat info o zmene vsem komponentam v systemu (spoustu z nich by to bylo jedno)
- komponenta obsahujici zajimavy stav (observable nebo publisher) implementuje List subscriberu a metody addListener, removeListener
- v pripade zmeny stavu informuje vsechny subscribery pres dodany callback
- komponenty zavisle na tomto stavu se zaregistruji (listener nebo subscriber)
Zajimave tridy
- Listenable (abstraktni trida s addListener() a removeListener())
- ValueListenable (pridava jen hodnotu typu T a jeji getter do Listenable)
- ChangeNotifier (implementuje Listenable interface a pridava List _listeners metodu notifyListeners(), ktera notifikuje subscribery)
- ValueNotifier (implementuje ChangeNotifier s jednou observable promennou typu T, implementuje take ValueListenable
) - ValueListenableBuilder (widget, ktery zabaluje vsechno dohromady - konstruktor sezere ValueListenable
a builder, ktery vyplivne child widget) - obvykle stav obsahuje vice promennych a pak se implementuje ChangeNotifier pro kazdou cast logiky - ma vice promennych definujicich stav a v prislusnych setterech nebo metodach vyvolava notifyListeners() metodu
- widget vlastnici instanci ChangeNotifier musi na nem ve vlastnim dispose() take zavolat changeNotifier.dispose()
- ListenableBuilder (handluje za nas pridavani/odebirani subscriberu, abchom je nezapomneli na spravnych mistech pridat/odebrat), na vstupu prebira obecny Listenable typ
- zrejme sam sebe subscribuje a pokud dojde k notifikaci tak zavola na sobe setState, aby to zpropagoval do childa?
Inherited Widget
- MediaQuery, Navigator a Theme jsou InheritedWidgety, ktere vklada do stromu WidgetsApp, ktery je vracen MaterialApp nebo CupertionApp
- obsahuje
bool updateShouldNotify(covariant InheritedWidget oldWidget)
, kde muzeme porovnat stary s novym po zmene a vyhodnotit, jestli dana zmena ma byt notifikovana (true) - pri implementaci definujeme statickou metodu of(), napr.:
class MediaQuery extends InheritedWidget {
final MediaQueryData data;
static MediaQueryData of(BuildContext context) {
return context.dependOnInheritedWidget<MediaQuery>()!.data;
}
}
dependOnInheritedWidget
hleda InheritedWidget daneho typu ve stromu smerem nahoru az k rootu, pokud ho najde, tak vrati v tomto pripadedata
, jinak vyhlasi error- krom navraceni InheritedWidgetu taky registruje volajici widget do zavislosti na danem InheritedWidgetu, s kazdou zmenou se pak vyhodnoti
updateShouldNotify
a pripadne provede build zavislych widgetu (presdidChangeDependencies
)