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 pripade data, 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 (pres didChangeDependencies)