React Hooks to nowość wprowadzona do Reacta od wersji 16.8. Co takiego dają i dlaczego warto się ich nauczyć? I na czym polegają w telegraficznym skrócie? O tym w nowej odsłonie cyklu “Jak się uczę”.
Seria wpisów Jak się uczę jest jedną z najstarszych na blogu. Jednak ostatnio trochę jej forma mnie znudziła, bo ile można dzielić się tylko linkami do materiałów. Postanowiłam przenieść ją na inny poziom i zacząć traktować trochę jak moje notatki. Znajdziecie tutaj od dzisiaj najważniejsze kwestie z zagadnień, które aktualnie zgłębiam. Oprócz linków do materiałów będzie kod i przykłady. Ruszamy!
Jeszcze mała uwaga – ten temat jest zdecydowanie dla osób, które znają już podstawy Reacta i umieją się w nich poruszać. Jak dopiero zaczynacie swoją przygodę z tą biblioteką, najpierw zajrzyjcie do polecanych przeze mnie materiałów do nauki. A jak już napiszecie pierwsze, przykładowe aplikacje, wróćcie tutaj.
React Hooks – z czym to się je?
Zacznijmy od początku, czyli czym są React Hooks (a w wersji spolszczonej – Hooki). Hooki to funkcje, które zawierają w sobie akcje odpowiedzialne za stan komponentu oraz jego tzw. lifecycle methods. Dzięki temu możemy korzystać w komponentach bezstanowych z metod dostępnych wcześniej tylko dla klas. W praktyce oznacza to tyle, iż jeżeli chcemy dodać do komponentu bezstanowego jakieś zachowania reagujące na stan – możemy to zrobić. Nie musimy przepisywać całego komponentu bezstanowego na klasę, jak trzeba było to robić wcześniej.
Hooki pozwalają nam zachować prosty układ komponentów, a jednocześnie używać dobrodziejstw stanu. Nasz kod może więc reagować na wszystkie lifecycle methods (takie jak np. componentDidMount czy componentDidUpdate) oraz zmieniać stan np. na kliknięcie na dany element.
Skąd ten stan?
Brzmi świetnie, ale jak tego użyć w praktyce? Bardzo fajny przykład podaje oficjalna dokumentacja Reacta, oczywiście jest to nieśmiertelny counter. Jak widać w przykładzie, aby modyfikować stan komponentu, wystarczy, iż użyjemy useState. Zwróćcie uwagę, iż przy deklaracji zmiennych counter i setCount korzystamy z destrukturyzacji tablicy, którą umożliwia ES6.
count z przykładu jest idealnym zobrazowaniem, jak łatwo zarządzać stanem dzięki Hookom. Teraz wystarczy tylko podpiąć metodą setCount do przycisku i podać jej odpowiednie argumenty do wywołania. Nic prostszego! Co więcej, React Hooks pozwalają nam na tworzenie kilku stanów. Nie musimy więc za każdym razem pamiętać, iż stan jest obiektem i pilnować, by przypadkiem nie nadpisać wartości, których nie chcemy zmienić (albo jakichś nie stracić). Dzięki Hookom możemy stworzyć kolejną zmienną, która będzie przechowywała inną część stanu (przykład z owocami w dokumentacji).
useEffect, czyli magiczny Hook
Dlaczego nazywam useEffect magicznym? Otóż umożliwia on obsługiwanie wszystkich side effects. Dzięki niemu obsłużmy w komponencie kod, za który wcześniej odpowiadał np. componentDidMount czy componentDidUpdate. Najpierw zajrzyjcie do dokumentacji, a poniżej zapraszam w końcu na moje przykłady!
Odliczamy czas!
Kiedyś znalazłam gdzieś tutorial prostego licznika, który odlicza czas do danej daty. Niestety, nie jestem w stanie odnaleźć źródła tego kodu, dlatego od razu zaznaczam – to nie jest mój pomysł. Postanowiłam wykorzystać bardzo prostą aplikację korzystającą z klas jako bazę. I przepisać ją z wykorzystaniem Hooków.
Zależało mi, żeby przepisywać coś, co już mam, bo założyłam, iż tak będzie mi się łatwiej uczyć. Pisanie kodu przy pomocy Hooków od zera nie pokazałoby mi dokładnie, co adekwatnie React Hooks zastępują. Bałam się, iż nie będę potem wiedziała, kiedy ich użyć.
Wyszłam od tego kodu – mam tutaj licznik, który odlicza czas do danej daty. Od razu zaznaczam – nie bawiłam się tutaj w walidację dat (bo to temat rzeka). Założyłam, iż chcę tu poćwiczyć używanie stanu i lifecycle methods. Dlatego nie zwracajcie uwagi na dziwne rzeczy, które dzieją się z licznikiem, gdy wpiszecie niepoprawny format daty. To, co może dziać się z datami, to ja akurat wiem baaardzo dobrze (ech, te godziny spędzone w pracy nad pewnym projektem ;)).
Wracając do tego prostego projektu – mam komponent App, który zawiera komponent Clock oraz input umożliwiający dodanie nowej daty. W komponencie App zmienia się stan w momencie wprowadzenia nowej daty. Data więc jest przetrzymywana właśnie w tym nadrzędnym komponencie i przekazywana jak props do Clock.
Komponent Clock na podstawie otrzymanej daty wylicza, ile pozostało do niej czasu. On także korzysta ze stanu oraz dodatkowo z lifecycle methods takich jak componentWillMount oraz componentWillUpdate. Pierwszy z nich pozwala uzyskać początkowy stan licznika, drugi odpowiednio zmienia licznik co sekundę, aby odliczanie się odbywało. Oba korzystają z metody getTimeUntil, która modyfikuje stan na postawie otrzymanego argumentu.
Po przekształceniach otrzymałam taki kod. Oba komponenty zmieniłam na funkcje, nie są już klasami. Komponent App korzysta z useState, aby ustawić datę. Datę w stanie zmienia metoda setDeadline, która jest wywoływana na wybranie odpowiedniej daty z date pickera (zamieniłam input na date picker, żeby choć w części przypadków uniknąć nieodpowiedniego formatu daty).
Dokładnie tak jak w wersji oryginalnej, deadline jest przekazywany do komponenty Clock jako props. Kompoennt Clock wykorzystuje metodę getTimeUntil, aby zmienić stany. Zauważcie, iż każda część mojego licznika jest teraz przechowywana w osobnym stanie, nie mam już jednego obiektu. O to, aby licznik odliczał czas oraz żeby rozpoczął odliczanie odpowiada Hook useEffect. Nie korzystam już z componentWillMount, ponieważ przestanie on być niedługo wspierany (więcej info tutaj). Dokumentacja podaje, iż jego odpowiednikiem w React Hooks jest po prostu useEffect. I gotowe!
Podsumowanie
Bardzo fajnie się bawiłam zmieniając już istniejący kod. Oczywiście to był dla mnie dopiero mini wstęp do Hooków, ale już nie mogę się doczekać, aż użyję ich do czegoś bardziej skomplikowanego! Zgłębiając Hooki korzystałam, oprócz oficjalnej dokumentacji, także z tego video. Mam zamiar teraz napisać coś właśnie na podstawie tego tutorialu (chciałabym wykorzystać Hooki do pobierania danych z API) i napisać swoje własne Hooki (tak, to też jest możliwe!).
Mam nadzieję, iż mój wpis choć trochę przybliżył Wam ideę React Hooks i zachęcił do ich przetestowania. Dajcie znać, czy będziecie pisać coś własnego z ich wykorzystaniem, a może już korzystacie z ich dobrodziejstw? Jak zwykle czekam maile na joanna@wakeupandcode.pl oraz na komentarze. Szczególnie zależy mi na Waszym feedbacku, więc napiszcie, jak sprawdziła się według Was taka nowa forma wpisów z tej serii.