W poprzednich postach opisywałem sposoby na zarządzanie stanem w React -Redux, Context API, MobX czy MobX State Tree – pewne problemy jednak pozostają nierozwiązane.
Powyższe rozwiązania sprawdzą się jako magazyn na dane – nie powiedzą nam jednak nic o systemie. Nie określą w jednoznaczny sposób możliwych stanów jakie wystąpią podczas działania aplikacji, nie walidują poprawności przejścia pomiędzy jednym stanem a drugim – musi o to zadbać ręcznie programista.
Często też wiedza o tych stanach ginie w trakcie rozwoju projektu – w miarę jak przybywa kodu i funkcjonalności, gdy odchodzą programiści znający system i przychodzą nowi, którzy muszą się go uczyć.
W rozwiązaniu tego problemu sprawdzają się skończone maszyny stanowe – definiują skończoną ilość dostępnych stanów i przejścia z jednego stanu w drugi.
Spis treści
- Czym jest skończona maszyna stanowa
- Biblioteka XState
- Integracja biblioteki XState z Reactem
- Podsumowanie
Czym jest skończona maszyna stanowa
W uproszczeniu o skończonej maszynie stanowej myśleć możesz jako o zestawie wszystkich stanów w jakiej znajduje się model wraz ze zdarzeniami, doprowadzającymi do przejścia z jednego stanu w drugi. Bardzo istotne jest to, że przejścia pomiędzy stanami są jasno określone – ze stanu X można przejść do Y tylko, jeżeli maszyna na to pozwala.
Czemu, jako frontendowiec, w ogóle miałbyś się interesować maszynami stanowymi? Ponieważ uczynią Twoją pracę znacznie prostszą – UI jako maszyna stanowa jest prostszy w zrozumieniu, łatwiej przypilnować przejść z jednego stanu w drugi. Prościej wejść w projekt, jeżeli możesz wejść w jeden plik który opisuje zachowanie danej części systemu zamiast szukać tych informacji po omacku w wielu plikach.
Ponadto, dzięki temu że maszyny stanowe można opisywać diagramami komunikacja z biznesem czy grafikiem za pomocą diagramów będzie dużo bardziej produktywna i zmniejszy się ilość niedomówień.
Biblioteka XState
Jedną z implementacji maszyny stanowej jaką możesz użyć w projekcie jest biblioteka XState.
XState visualizer
Zaletą maszyny stanowej XState (i maszyn stanowych w ogólności) jest to, że możesz ją wizualizować. Biblioteka XState dostarcza narzędzia Visualizer. Możesz nawet na bieżąco podglądać, jak wygląda diagram Twojej maszyny podczas kodowania jej w edytorze na stronie.
Przykładowo maszyna:
Wygląda następująco:

W kodzie maszyny celowo użyłem tzw dynamic property key – jeżeli np zdecydowalibyśmy się na zmianę standardów, np nazwa stanu pisana wielkimi literami a nazwa zdarzenia małymi, zmienić trzeba będzie tylko w jednym miejscu. Gorąco zachęcam Cię do takiego podejścia.
Maszyna stanowa
Diagram bardziej skomplikowanej maszyny stanowej mógłby się przedstawiać następująco:

Logika wygląda tak:
- Na początku maszyna znajduje się w stanie
unathorized
- Akcja
LOGIN
powoduje przejście do stanuloading
- Stąd akcja
RESOLVE
powoduje przejście do stanusuccess
, z którego akcjąLOGOUT
można przejść z powrotem do stanuunauthorized
- Akcja
REJECT
powoduje przejście do stanufailure
, z którego akcjaRETRY
przeniesie nas do stanuunathorized
ale tylko wtedy, jeżeli zostały jakieś próby logowania.
Integracja biblioteki XState z Reactem
Stwórz proszę nową aplikację CRA. Po zainstalowaniu biblioteki głównej oraz jej paczki integracji z Reactem:
Masz do dyspozycji hook zwracający stan oraz funkcję, która umożliwia wysyłanie zdarzeń do maszyny:
state
udostępnia funkcję matches
do sprawdzania, czy maszyna znajduje się w określonym stanie:
Stwórz UI umożliwiające wysyłanie zdarzeń do maszyny stanowej:
Kod zakłada, że w pliku authMachine
znajduje się zdefiniowana wyżej maszyna stanowa – z tą różnicą, że wszystkie stałe są wyeksportowane, by móc użyć ich w pliku głównym.
Jeżeli już przekopiowałeś, uruchomiłeś i przeklikałeś aplikację zauważysz, że klikając przycisk Always visible retry
stan zmienia się tylko wtedy, jeżeli maszyna jest w stanie failure
. Dzieje się tak, ponieważ przejścia między stanami muszą być zdefiniowane jawnie – upraszcza to konstrukcję UI.
Podsumowanie
Maszyny stanowe pozwalają grupować w jednym miejscu wiedzę o tym, jak działa system. Ich użycie zwiększa przewidywalność zachowań systemu, ułatwiają też komunikację z osobami nietechnicznymi dzięki temu, że można opisać je jako diagram – szczególnie, że biblioteka XState dostarcza dedykowane wizualizacji narzędzie.
Warto rozważyć ich zastosowanie w projektach frontendowych.