Aplikacje Mobilne Strona 1
Aplikacje mobilne
React hooks i axios
Mateusz Pawełkiewicz
Aplikacje Mobilne Strona 2 Axios – to oparty na obietnicach klient HTTP dla node.js i przeglądarki. Jest izomorficzny (=
może działać w przeglądarce i nodejs z tą samą bazą kodu). Po stronie serwera korzysta z natywnego modułu http node.js, natomiast po stronie klienta (przeglądarki) korzysta z XMLHttpRequests.
Instalacja axiosa npm install axios yarn add axios
Jakie możliwości dostarcza nam axios:
- Wykonuje żądania http z node.js - Obsługuje interfejs Promise API - Przechwytuje żądanie i odpowiedź - Przekształca dane żądania i odpowiedzi - Anuluje prośby
- Wsparcie po stronie klienta w celu ochrony przed XSRF (Cross-site request forgery)
XSRF - Fałszowanie żądań między witrynami, znane również jako atak jednym kliknięciem lub jazda sesyjna i w skrócie CSRF (czasami wymawiane sea-surf[1]) lub XSRF, to rodzaj
złośliwego exploita witryny internetowej, w której nieautoryzowane polecenia są przesyłane od użytkownika któremu ufa aplikacja internetowa.[2] Istnieje wiele sposobów, w jakie złośliwa witryna internetowa może przesyłać takie polecenia; Na przykład specjalnie spreparowane tagi obrazu, ukryte formularze i JavaScript XMLHttpRequests mogą działać bez interakcji użytkownika, a nawet wiedzy. W przeciwieństwie do skryptów między witrynami (XSS), które wykorzystują zaufanie użytkownika do określonej witryny, CSRF wykorzystuje zaufanie, jakie witryna ma do przeglądarki użytkownika.
Axios obsługuje takie żądania jak:
axios.request(config) axios.get(url[, config]) axios.delete(url[, config]) axios.head(url[, config]) axios.options(url[, config]) axios.post(url[, data[, config]]) axios.put(url[, data[, config]]) axios.patch(url[, data[, config]])
Aplikacje Mobilne Strona 3 Przykład żądania GET w axios
Przykład żądania POST w axios
Konfiguracja axiosa 1. Globalnie
2. Lokalnie
Aplikacje Mobilne Strona 4 Interceptors
Możemy przechwytywać żądania lub odpowiedzi, zanim zostaną one obsłużone.
Najpopularniejszym wykorzystaniem interceptora jest przechwycenie kodu błędu 401.
Hooki
Hooki są nowym dodatkiem w Reakcie od wersji 16.8. Pozwalają one używać stanu i innych funkcjonalności Reacta, bez użycia klas.
Aplikacje Mobilne Strona 5 Podstawowe hooki
useState
const [state, setState] = useState(false);
Zwraca zmienną przechowującą lokalny stan i funkcję do jego aktualizacji.
Podczas pierwszego renderowania zwrócona wartość stanu (state) jest taka sama, jak wartość przekazana jako pierwszy argument (initialState).
Funkcja setState jest używana do aktualizacji stanu. Przyjmuje ona nową wartość stanu i kolejkuje ponowne renderowanie komponentu.
setState(newState);
Podczas kolejnych ponownych renderowań pierwszą wartością zwracaną przez useState będzie zawsze najnowszy, zaktualizowany stan.
Jeżeli nowy stan wyliczany jest z poprzedniego, możesz przekazać funkcję jako argument do setState. Funkcja otrzymuje poprzednią wartość stanu, a zwraca nową, zaktualizowaną wartość. Oto przykład komponentu licznika, który wykorzystuje obie formy setState:
Przyciski „+” i „-” wykorzystują formę funkcyjną, ponieważ zaktualizowana wartość bazuje na poprzedniej. Z kolei przycisk „Zresetuj” używa normalnej formy, ponieważ zawsze przywraca początkową wartość.
Jeśli funkcja aktualizująca zwróci wartość identyczną z aktualnym stanem, nie spowoduje to ponownego wyrenderowania.
W przeciwieństwie do metody setState znanej z komponentów klasowych, funkcja useState nie scala automatycznie obiektów reprezentujących aktualizację. Możesz powielić to
zachowanie, łącząc formę aktualizacji funkcyjnej ze składnią operatora rozszczepienia (ang.
spread operator) obiektu:
Aplikacje Mobilne Strona 6
useEffect
useEffect(didUpdate);
Przyjmuje funkcję zawierającą imperatywny kod, mogący zawierać efekty uboczne.
W ciele głównej funkcji komponentu (określanej jako faza renderowania Reacta) nie jest dozwolone mutowanie danych, tworzenie subskrypcji, timerów, logowanie i inne efekty uboczne. Robiąc tak należy spodziewać się mylących błędów i niespójności w interfejsie użytkownika.
Zamiast tego użyj useEffect. Funkcja przekazana do useEffect zostanie uruchomiona po tym, jak zmiany zostaną wyświetlone na ekranie. Należy traktować efekty jako furtkę pomiędzy czysto funkcyjnym światem Reacta, a imperatywnym światem.
Domyślnie efekty są uruchamiane po każdym wyrenderowaniu komponentu, ale możesz sprawić, że uruchomią się tylko jeżeli zmienią się jakieś wartości.
Czyszczenie po efekcie
Często efekty tworzą zasoby (np. subskrypcję czy ID timera), które należy uprzątnąć zanim komponent opuści ekran. Aby to uczynić funkcja przekazywana do useEffect może zwracać funkcję czyszczącą. Na przykład przy tworzeniu subskrypcji:
Aby zapobiec wyciekom pamięci, funkcja czyszcząca wywoływana jest zanim komponent zostanie usunięty z interfejsu użytkownika. Dodatkowo jeśli komponent jest renderowany kilkukrotnie (co zwykle ma miejsce), poprzedni efekt jest czyszczony przed wywołaniem kolejnego efektu. W naszym przykładzie oznacza to, że nowa subskrypcja tworzona jest przy każdej aktualizacji. W kolejnym podrozdziale opisujemy, jak uniknąć wywoływania efektów przy każdej aktualizacji.
Aplikacje Mobilne Strona 7 Harmonogram efektów
W przeciwieństwie do metod componentDidMount i componentDidUpdate funkcja przekazana do useEffect wywoływana zostanie po tym jak skomponowany i namalowany zostanie układ strony. Sprawia to, że nadaje się ona do obsługi wielu typowych efektów ubocznych, takich jak tworzenie subskrypcji czy obsługa zdarzeń. Większość tego typu operacji nie powinna powstrzymywać przeglądarki przed odświeżeniem widoku.
Jednakże nie wszystkie efekty mogą zostać odroczone. Na przykład manipulacja drzewem DOM, widoczna dla użytkownika, musi zostać wywołana synchronicznie przed każdym malowaniem, tak aby użytkownik nie dostrzegł wizualnej niespójności. (Rozróżnienie to w swej koncepcji podobne jest do pasywnych i aktywnych obserwatorów zdarzeń (ang. event listeners).) Dla tego typu efektów React przewiduje dodatkowy hook, nazwany
useLayoutEffect. Ma on tę samą sygnaturę co useEffect, różnie się jedynie tym, kiedy jest wywoływany.
Warunkowe uruchamianie efektów
Domyślnym zachowaniem efektów jest ich uruchamianie po każdym pomyślnym renderze.
W ten sposób efekt jest zawsze tworzony na nowo, jeśli zmieni się jedna z jego zależności.
Jednakże w pewnych przypadkach może się to okazać zabójcze - choćby w przykładzie subskrypcji z poprzedniego podrozdziału. Nie ma potrzeby tworzyć nowej subskrypcji przy każdej aktualizacji, a jedynie wtedy, gdy zmieni się właściwość source.
Aby zaimplementować takie zachowanie należy przekazać do useEffect drugi argument, będący tablicą wartości, od których zależy efekt. Nasz zaktualizowany przykład wygląda następująco:
Teraz subskrypcja zostanie stworzona ponownie tylko wtedy, gdy zmieni się właściwość props.source.
Aplikacje Mobilne Strona 8 useContext
const value = useContext(MyContext);
Kiedy używać kontekstu?
Konteksty zaprojektowano do współdzielenia danych, które można uznać za “globalne” dla drzewa komponentów, takich jak informacje o zalogowanym użytkowniku, schemat kolorów czy preferowany język.
Zwykle kontekstu używa się w sytuacjach, w których pewne dane muszą być dostępne dla wielu komponentów na różnych poziomach zagnieżdżenia. Z mechanizmu tego należy korzystać z rozwagą, ponieważ utrudnia on wielokrotne używanie komponentów zależnych.
Aplikacje Mobilne Strona 9 Rozważmy komponent Page, który musi przekazać właściwości user oraz avatarSize kilka poziomów w dół, tak aby głęboko zagnieżdżone komponenty Link i Avatar mogły je odczytać:
Przekazywanie tych wartości przez tyle poziomów, tylko po to by mógł je odczytać Avatar, wydaje się lekką przesadą. Dodatkowo, gdyby Avatar w pewnym momencie zaczął wymagać jeszcze jednej wartości z góry, należałoby ją również przekazać przez te wszystkie poziomy.
Zaawansowane hooki useReducer
const [state, dispatch] = useReducer(reducer, initialArg, init);
Alternatywa dla hooka useState. Przyjmuje reduktor (ang. reducer), będący funkcją o sygnaturze (stan, akcja) => nowyStan, a zwraca aktualny stan w parze z metodą dispatch.
Aplikacje Mobilne Strona 10 useReducer sprawdza się lepiej od useState tam, gdzie występuje skomplikowana logika związana ze stanem, obejmująca wiele pod-wartości lub gdy następny stan zależy od poprzedniego. useReducer pozwala też zoptymalizować wydajność komponentów
uruchamiających głębokie aktualizacje, ponieważ zamiast przekazywać funkcje zwrotne (ang.
callback), możesz przekazać funkcję dispatch w dół drzewa.
useMemo
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Zwraca zapamiętaną (ang memoized) wartość.
Przekaż funkcję tworzącą i tablicę zależności. useMemo obliczy ponownie zapamiętaną wartość tylko wtedy, gdy zmieni się któraś z zależności. Ta optymalizacja pozwala uniknąć kosztownych obliczeń przy każdym renderowaniu.
Pamiętaj, że funkcja przekazana do useMemo uruchamiana jest podczas renderowania. Nie należy w niej robić niczego, czego normalnie nie robiono by podczas renderowania. Na przykład wszelkie efekty uboczne przynależą do useEffect, a nie useMemo.
Jeśli nie zostanie przekazana żadna tablica, nowa wartość będzie obliczana przy każdym renderowaniu.
useRef
const refContainer = useRef(initialValue);
useRef zwraca mutowalny (ang. mutable) obiekt, którego właściwość .current jest
inicjalizowana wartością przekazaną jako argument (initialValue). Zwrócony obiekt będzie trwał przez cały cykl życia komponentu.
Częstym przypadkiem użycia jest imperatywny dostęp do potomka:
Aplikacje Mobilne Strona 11
Literatura
https://pl.reactjs.org/docs/hooks-intro.html https://axios-http.com/docs