Mobilne Aplikacje z React
5 godz. 51 min · React Native · Full-stack i Programowanie
Piotr SzacińskiZarówno iOS jak i Android posiadają swoje natywne SDK, do obsługi którego musimy poznać nowe języki - Swift czy Kotlin, o Objective-C czy Javie nie wspominając. Z kolei React Native jest do tego świetną alternatywą, która pozwala tworzyć jeden kod na obie platformy. Dodatkowo - bazuje na najpopularniejszym frameworku webowym, co znacząco zmniejsza próg wejścia.
Tak samo jak "czysty" React, React Native opiera się na komponentach. Poznasz ich specyfikę i nauczysz się poprawnie budować UI aplikacji. Zrozumiesz też jak najwydajniej zarządzać skomplikowanym layoutem, takim jak długie listy, i jak to wszystko łatwo stylować.
Animacje to nie tylko efekty przyjemne dla oka - to przede wszystkim dobry UX, który pozwala użytkownikowi odnaleźć się w aplikacji i zrozumieć jej mechanikę. Podczas kursu poznasz wszystkie podstawowe metody i koncepcje tworzenia animacji oraz poznasz sposoby optymalizacji ich działania. Dodatkowo omówimy prawidłowe podejście do dużo bardziej skomplikowanych interaktywnych animacji, przedstawimy ciekawe biblioteki oraz best-practices.
Praktycznie każda aplikacja, niezależnie od tego, czy web, czy mobile, składa się z wielu widoków i ekranów. Zarządzanie ścieżkami, jakimi użytkownik może się poruszać, to jedna z najważniejszych rzeczy - a w tym kursie dowiesz się jakich narzędzi należy używać i jak łatwo obsługiwać zagnieżdżone ekrany.
Niewątpliwym atutem aplikacji jest to, że może praktycznie bez ograniczeń przechowywać content w urządzeniu telefonu, a przez to - dostarczać treści niezależnie od dostępności internetu. Omówimy różne koncepcje zapisywania danych oraz poznamy metody i narzędzia do ich wdrażania.
Przybliżymy ci proces wypuszczania aplikacji "w świat" oraz przedstawimy narzędzia, z których sam autor korzysta do ułatwienia tego procesu.
Kurs jest dla każdego kto zna podstawy JavaScript oraz React i chciałby się rozwijać i tworzyć mega ciekawe projekty, które mogą używać aparatu czy sensorów smartfona.
0.62.2+
Czyli w ostatniej lekcji robiliśmy sobie jakąś listę pokazaliśmy
sobie jakie tutaj użyliśmy różnych propsów jakie dana lista nam daje i chciałem
wam pokazać jeszcze w tej chwili taką rzecz na którą zapewne na początku nie natraficie
ale warto warto gdzieś tam z tyłu głowy to mieć chodzi tutaj o
optymalizację tej listy znaczy tak jak samo FlatList zoptymalizowało nam
działanie tego dość diametralnie tak sama FlatLista sama
w sobie też jest do zoptymalizowania w pewnych case'ach żeby
to pokazać to wrócimy sobie do naszego przykładu który usunąłem
ale to zaraz odtworzymy wygenerujemy
sobie trochę elementów
ważna rzecz to jest funkcja Array
from Array map okej sprawdźmy to okej
i wyrendrowało mam całkiem dużo elementów i spoko to samo
możemy tutaj zrobić w androidzie i zapewne jak będziemy
teraz scrollować tak jest to nasza lista działa całkiem fajnie natomiast chciałbym żebyśmy
zwrócili uwagę na jedną rzecz przejdźmy sobie do naszego do flippera
React Native okej i
zauważcie tak jak mówiłem na początku ta metoda ona
mówi nam o renderowaniu elementów czyli kiedy ten element jest renderowany a nie kiedy
tworzony i zobaczmy kiedy tak naprawdę te elementy są
renderowane czyli próbujmy to sobie Render
list item i przekażmy nazwę
tego itemu zobaczmy co tu się co
tu się stanie nic się nie dzieje uruchomimy sobie flippera
jeszcze raz możliwe że gdzieś tam nam się pogubił
okej mamy dodam tutaj Elem
patrzcie co się dzieje w
trakcie pisania tekstu czyli kiedy zmienia nam się nasz state
naszej listy tutaj dokładnie
tutaj czyli kiedy zmieniam currentText za każdym razem
renderuje się renderują się wszystkie elementy listy to uwaga
co się stanie jak ja dodam tutaj dodam te elementy
zauważcie co się dzieje tak wszystkie te elementy są
renderowane jeśli ja to zacznę pisać to one wszystkie
1000 elementów jest renderowane na tym może symulatorze iOS-a może to nie będzie widoczne ale
tutaj już być może zacznie się coś ciąć a na pewno te
logi temu nie pomogą tak i tutaj jest oczywiście
problem typowo Reactowy nie ma jakiegoś większego związku z React
Nativem natomiast o dostaliśmy nawet komunikat chciałbym
do niego dobrze mieć o you have a large list
that is slow to update make sure you renderIthem function render component that follow React
performance best practices like Pure Component i dokładnie to jest sedno
od którego musimy zacząć naszą optymalizację i tak naprawdę jeśli wiemy że ta lista będzie dynamiczna
i będzie miała wiecej elementów to od tego musimy zacząć to znaczy
nasz element listy powinien być pure nad komponentem w
przypadku elementów klasowych oczywiście musielibyśmy nadpisać
metodę suit update suit component update
natomiast w przypadku komponentów funkcyjnych z których ja korzystam mamy taką metodę
jak memo która nam tak naprawdę z tego komponentu po
prostu robi pure component
wyczyśćmy sobie logi odświeżmy
aplikację zauważcie co się dzieje zaczynam
pisać nic się nie dzieje dopiero jak dodam to
zaczynają być te compenty renderowane tak i to jest pierwsza rzecz o której należy pamiętać
i pokażę jeszcze jeden case o którym równie łatwo można
zapomnieć załóżmy że chcielibyśmy żeby tym i tym
się dało kliknąć czyli co zrobimy zmieniamy sobie to na TouchableOpacity
tutaj dodajemy onPress
i przekażmy jakiegoś propsa
onItemPress okej
i tutaj na przykład zróbmy tak żeby w tym onItemPress
przekazywać nasze info na naszej
liście natomiast tutaj dodamy sobie tak dodamy sobie tutaj metodę
do obsługi tego i
tutaj a damy jakiegoś loga
onItemPress onItemPress
świetnie bailando czyścimy
logi odpalmy na nowo zreload'ujmy nasz
projekt zaczynam pisać no i
kurczę znowu wszystkie elementy zaczynają się renderować w momencie pisania czemu
tak jest no to jest oczywiście problem samych hooks'ów a nie React Native'u czy nawet
właściwie samego Reacta jak ale
ławo o tym zapomnieć i tak jak często nie robi to wielkiej różnicy bo
React sam w sobie jest szybki i React Native sam w sobie też jest bardzo szybki i sprawdzanie
ktore elementy się zmieniły jak je renderować to nie jest jakiś olbrzymi problem to że wywołała
nam się ta funkcja to nie znaczy że ten element nam się faktycznie wyrenderował aczkolwiek wymagało
to jakiegoś zasobu a zwłaszcza jak lista jest długa no i teraz w
czym jest problem no problem jest w tym że nasz
Pure Component widzi za każdym razem zmianę item pressu dlaczego dlatego
że ta funkcja z każdym renderem tej funkcji jest tworzona nowa tak
jeśli byśmy na przykład w drugim argumencie naszego memo na
sztywno zahardkodowali zmianę true odświeżmy sobie
tą listę reload wyczyśćmy
to w tej chwili już problemu nie ma tak no tylko że wtedy do końca nie
wiemy jak mamy tą listę odświeżać tak to znaczy
jesli coś by sie w tej liście zmieniło w tym elemencie tej listy no to on
i tak by się nie nie odświeżył teraz jak sobie z
tym poradzić najlepiej znaczy właśnie najlepiej jedyna
właściwa opcja to jest użycie useCallbacka i tak jak mówiłem
raczej nie będę się tutaj skupiać na tych typowo hooksowych
czy Reactowych rzeczach ale warto warto mieć to z tyłu głowy bo łatwo
o tym zapomnieć a przypadku FlatListy jest to wydajność jest mega istotna to
jest pierwsza rzecz o której trzeba pamiętać żeby na pewno nasz element listy był pure componentem a
jeśli używamy jakichś Callbacków a pewnie używamy to trzeba ja opakować
w useCallback odpalny sobie jeszcze raz nasz komponent znaczy
zbundle'ujmy wszystko no i zauważcie że teraz w trakcie pisania juz jest okej i
to jest pierwsza optymalizacja od której w ogóle powinniśmy zaczynać
natomiast mamy trochę więcej możliwości pierwszy element który
w którym moglibyśmy coś zoptymalizować
to jest windowSize ten windowSize
mówi nam o tym ile widoków
przygotowanych itemów trzymać czyli jeśli na przykład zaznaczylibyśmy
tutaj 1 to to by znaczyło tyle że nasz nasza lista
trzymałaby w pamięci tylko tyle elementów ile mieści się na jednym ekranie
w momencie scrolla dopiero te elementy byłyby tworzone i to będzie
fajnie widać tutaj jeśli dodamy jakieś elementy
i patrzcie widzicie jakby
nie da się nawet do końca scrollować bo te elementy są dopiero tworzone zobaczmy jak to wygląda na iOS-ie
widzicie jakby widać gdzie te elementy są
tworzone i te białe elementy wynikają z tego że
po prostu React nie zdąży tego wyrenderować no bo my robimy szybkiego scrolla a już
żądamy żeby pełen widok był wyrenderowany i dochodzimy tutaj
do takiego momentu w którym często trzeba wyważyć szybkość działania z
płynności działania czyli z niepłynnością działania tylko płynnością wyświetlania czyli z jednej strony chcielibyśmy
żeby lista jak najszybciej działała w naszym przypadku gdzie jest tak prosta
nie będzie z tym problemu ale jeśli elementy byłyby bardziej skomplikowane miały jakieś grafiki na sobie
to byłoby to już bardzo zauważalne zwłaszcza na słabszych telefonach no i w
związku z tym możemy się tym parametrem pobawić i ustawić on domyślnie ma wartość zdaje się że 20 czyli bardzo
dużą natomiast już samo ustawienie 3 powinno trochę tą sytuację poprawić
spróbujmy dodajmy
jakieś elementy okej już jest lepiej tak w sensie widać że
dalej dojeżdżamy do momentu gdzie się ta lista kończy i przy szybkim scrollu walimy
powiedzmy o ścianę ale już jest lepiej tak i przy szybkim scrollu w górę też co się dzieje pamietajmy też o tym
że no te logi które są wyświetlane też dodają swoje
bo jednak trzeba je wyświetlić w trakcie takiego scrolla dzieje się to co pokazywałem o
widzieliście te białe obszary to jest dokładnie to o czym mówiłem w przypadku
bridge'a tak znaczy sie ta komunikacja bridge'owa nie nadąża zwłaszcza
w trybie debugowym gdzie dużo więcej rzeczy jest przesłanych i mniej rzeczy jest zoptymalizowanych
i jeszcze wyswietlane sa logi więc jeśli
będziecie mieli problem z listą no to to jest pierwsza rzecz którą można
się pobawić inny element to jest removeClippedSubviews
i ten element to jest odpowiedzialne
za pamięć tak czyli można napisać że to jest memory czyli
to nam będzie trzymało tylko tyle ekranów z tymi itemami w
pamięci natomiast to nam będzie te widoki odczepiać
lub zaczepiać czyli to nie będzie miało aż takiego dużego wpływu na pamięć
ale na wydajność listy już może mieć przy czym warto zdać sobie sprawę
że proszę bardzo tutaj jest opis tego oficjalny
note may have bugs missing content is some circumstances use at your own risk
to jest zwłaszcza widoczne na iOS-ie w pewnych sytuacjach no generalnie
ja bym tego nie używał ale jeśli będziecie mieli problem z wydajnością listy to
warto na taki parametr zerknąć kolejną
rzeczą która może pomóc to jest predefiniowanie rozmiaru
naszych itemów jeśli nasze itemy mają zdefiniowany
rozmiar a w naszym przypadku mają to możemy pozwolić
zamiast pozwalać Reactowi na wyliczanie wysokości
każdego itemu który teraz jest oczywiście na sztywno możemy mu narzucić ten rozmiar
i to napewno przyśpieszy też naszą listę jaki ten layout oczywiście zapomniałem
o jeszcze raz
data index i nie dwukropek tylko równa się
oczywiście o i
teraz tak możemy podać index czyli to będzie akurat nasz index
musimy podać length zdaje się
to jest wysokość czyli nie wiem na przykład 80
to jest nasz na sztywno i możemy podać jeszcze offset czyli
to jest wysokość na której ten element się znajduje no i w naszym wypadku jeśli mamy na sztywno wysokość
to będzie po prostu 80 razy index tak to jest nie
nadążył ESLint świetnie no i ta lista już w tym momencie jest dużo bardziej zoptymalizowana
mówiłem tutaj nie będzie aż tak to widoczne ciężko mi na szybko zrobić taką listę w której byłoby
to widać ale to jest już coś nad tym nad czym
możecie popracować żeby tą listę
poprawić jest jeszcze jedna rzecz o której chciałem powiedzieć jeśli
byśmy sobie to to wyeksportowali
i na przykład na starcie tej listy
dodali jako elementy startowe to zauważcie
odświeżmy to że to też może chwilę potrwać może
tego tu nie będzie aż tak bardzo widać a zwłaszcza że nam android gdzieś tam ucina się ale
może być widać pewien lag zwłaszcza na słabszych urządzeniach i żeby nie
było konieczności w której on musi jakby lista musi analizować czy wyświetlać
tą całą listę nie może jakby nie wyświetla całej ale jednak
musi wziąć pod uwagę całą listę to możemy sobie zrobić coś takiego jak initialNumToRender
i to nam mówi o tym ile elementów tak naprawdę
na starcie ta lista ma wyświetlić warto zrobić mniej więcej tyle ile się
mieści na dwóch ekranach czyli 20 w tym momencie jak
odpalimy sobie aplikację na nowo zbuduje nam się to ten start będzie
dużo szybszy bo ta lista będzie składała się
dopiero z 20 elementów i w trakcie scrollowania ona dopiero zacznie się doładowywać
tych elementów jest dużo więcej pełne pełen opis tego w
jaki sposób sobie radzić z optymalizacją całej listy znajduje się właśnie na
stronie reactnative.dev/docs/optimizing-flatlist-configuration i tutaj mamy mniej więcej
to o czym mówiliśmy czyli initialNumToRender
windowSize i parę innych rzeczy o tym żeby używać właśnie light componentów
żeby używać ComponentUpdate i tak dalej i tak dalej ale mamy też parę innych rzeczy i jeśli
dojdziecie do ściany to warto się czymś takim zainteresować i
poczytaj sobie o tej liście natomiast jest jeszcze jedno rozwiązanie które nie jest oficjalne czyli
nie jest elementem listy FlatListy nazywa się RecyclerListView i to jest element który
mocno bazuje na RecyclerView androidowym i on działa tak że faktycznie
te elementy których nie widzimy są recreate'owane czyli jeśli
ja mam tu element 0 scrolluje tą listę o to w tym momencie ten element 0
zaczyna się pojawiać tutaj tak jakby i cały czas ten tych elementów stworzonych
trzymany w pamięci jest maksymalnie tyle ile jest na ekranie plus minus jakiś tam margines więc
to jest naprawdę szybkie i jesli nasza lista składa się z bardzo powtarzalnych
elementów albo jesteśmy w stanie określić po prostu ich wysokość to to jest super rozwiązanie
czyli tutaj są przykłady takich list w których mamy takie same elementy natomiast sama implementacja jest
trochę bardziej skomplikowana bo wymaga wypełnienia takich rzeczy jak właśnie z góry
predefiniowanie rozmiarów czyli to coś co robiliśmy tutaj i
jeszcze parę innych rzeczy natomiast może być tak że to nam uratuje
skórę i że w sytuacji trochę takie jak nasza tutaj sprawimy że ta lista
będzie dużo bardziej zoptymalizowana myślę że to tyle jeśli chodzi o optymalizację tej listy
tak czy siak mimo tego że to jest całkiem zaawansowana zaawansowany
komponent który jeszcze tak jak mówię dziedziczy po tym bardziej zaawansowanym VirtualizedList to
w praktyce to co nas będzie interesować to są trzy rzeczy ewentualnie jeszcze
ten Header i Footer i to powinniście zapamiętać i wynieść z tej lekcji.