React Native EU dobiegło końca. Ponad 300 uczestników z 33 krajów odwiedziło Wrocław. Wystąpienia można znaleźć na YouTube.
Po konferencji powoli wracamy do naszego harmonogramu open source. Warto wspomnieć, że pracujemy nad kolejną wersją react-native-opentok, która naprawia większość istniejących problemów.
Staramy się obniżyć próg wejścia dla deweloperów zaczynających przygodę z React Native, wprowadzając:
Ogłoszono BuilderX.io na React Native EU. BuilderX to narzędzie projektowe, które bezpośrednio współpracuje z plikami JavaScript (obecnie obsługiwane jest tylko React Native) w celu generowania pięknego, czytelnego i edytowalnego kodu.
Uruchomiono ReactNativeSeed.com dostarczający zestaw szablonów dla twojego kolejnego projektu React Native. Oferuje różne opcje, w tym TypeScript i Flow do typów danych, MobX, Redux oraz mobx-state-tree do zarządzania stanem, z CRNA i czystym React-Native jako stosem technologicznym.
Wkrótce wydamy SDK 21, dodające obsługę react-native 0.48.3 oraz zestaw poprawek błędów, ulepszeń stabilności i nowych funkcji w Expo SDK, w tym nagrywanie wideo, nowe API ekranu startowego, obsługę react-native-gesture-handler oraz ulepszoną obsługę błędów.
Odnośnie react-native-gesture-handler, Krzysztof Magiera z Software Mansion kontynuuje rozwój tej biblioteki, a my wspieramy go testami i finansowaniem części czasu deweloperskiego. Integracja z Expo w SDK21 pozwoli łatwo eksperymentować z nią w Snacku - nie możemy się doczekać, co społeczność stworzy.
Odnośnie ulepszonego logowania/obsługi błędów - szczegóły implementacji znajdziesz w tym gist wewnętrznego PR Expo (szczególnie "Problem 2") oraz w tym commicie dotyczącym obsługi błędów importu standardowych modułów npm. To doskonała okazja do ulepszania komunikatów błędów w samym React Native - planujemy kolejne PRe i zachęcamy społeczność do współpracy.
Pracujemy nad ulepszeniem komponentów <Text> i <TextInput> na Androida (natywne automatyczne powiększanie <TextInput>; problemy układu głęboko zagnieżdżonych <Text>; lepsza struktura kodu; optymalizacje wydajności).
Wciąż poszukujemy dodatkowych współtwórców do pomocy w triage'owaniu zgłoszeń i pull requestów.
Wydano funkcję podpisywania kodów (Code Signing) dla CodePush. Deweloperzy React Native mogą teraz podpisywać swoje pakiety aplikacji w CodePush. Ogłoszenie można znaleźć tutaj
Pracujemy nad ukończeniem integracji CodePush z Mobile Center. Rozważamy także integrację testów i raportowania awarii (test/crash integration).
Kolejna sesja odbędzie się w środę, 10 października 2017 roku. Ponieważ to dopiero nasze czwarte spotkanie, chcielibyśmy wiedzieć, jak te notatki przynoszą korzyści społeczności React Native. Śmiało daj mi znać na Twitterze, jeśli masz sugestie, jak możemy ulepszyć rezultaty tych spotkań.
Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt.
Znalazłeś błąd? Zgłoś problem →
Miesięczne spotkanie React Native trwa! Tym razem było nieco krótsze, ponieważ większość zespołów była zajęta wydawaniem produktów. W przyszłym miesiącu spotkamy się na konferencji React Native EU we Wrocławiu. Koniecznie zdobądź bilet i do zobaczenia na miejscu! Tymczasem sprawdźmy, czym zajmują się nasze zespoły.
Niedawno otworzyliśmy źródła react-native-material-palette. Narzędzie wyodrębnia dominujące kolory z obrazów, pomagając tworzyć wizualnie atrakcyjne aplikacje. Obecnie działa tylko na Androida, ale planujemy dodać wsparcie dla iOS.
Wdrożyliśmy obsługę HMR w haul oraz mnóstwo innych fajnych funkcji! Sprawdź najnowsze wydania.
React Native EU 2017 już wkrótce! Cały przyszły miesiąc poświęcony React Native i Polsce! Koniecznie złap ostatnie bilety tutaj.
Wprowadziliśmy obsługę instalacji pakietów npm w Snack. Obowiązują standardowe ograniczenia Expo — pakiety nie mogą używać niestandardowych natywnych API niewbudowanych w Expo. Pracujemy też nad obsługą wielu plików i przesyłaniem zasobów w Snack. Satyajit opowie o Snacku na React Native Europe.
Wydaliśmy SDK20 z aparatem, płatnościami, bezpiecznym przechowywaniem, magnetometrem, wstrzymywaniem/wznawianiem pobierania plików oraz ulepszonym ekranem powitalnym/ładowania.
Kontynuujemy współpracę z Krzysztofem nad react-native-gesture-handler. Wypróbujcie bibliotekę, odtwórzcie gesty zbudowane wcześniej w PanResponder lub natywnych rozpoznawaczach i dajcie znać o napotkanych problemach.
Eksperymentujemy z protokołem debugowania JSC, pracujemy nad wieloma zgłoszeniami funkcji na Canny.
W zeszłym miesiącu omawialiśmy zarządzanie śledzeniem problemów na GitHubie i zapowiedzieliśmy poprawy w utrzymywalności projektu.
Liczba otwartych zgłoszeń utrzymuje się na poziomie ~600 i prawdopodobnie pozostanie taka jakiś czas. W ostatnim miesiącu zamknęliśmy 690 zgłoszeń z powodu braku aktywności (definiowanej jako brak komentarzy w ciągu 60 dni). Spośród nich 58 zostało ponownie otwartych z różnych powodów (opiekun zadeklarował poprawkę lub współtwórca przekonująco uzasadnił utrzymanie zgłoszenia).
Planujemy kontynuować automatyczne zamykanie nieaktywnych zgłoszeń w przewidywalnej przyszłości. Chcielibyśmy osiągnąć stan, w którym każde istotne zgłoszenie w repozytorium jest rozpatrywane, ale jeszcze tam nie jesteśmy. Potrzebujemy wszelkiej możliwej pomocy od maintainerów w klasyfikowaniu zgłoszeń, aby nie przeoczyć problemów powodujących regresje lub zmiany łamiące kompatybilność, szczególnie tych wpływających na nowo tworzone projekty. Osoby zainteresowane pomocą mogą używać Facebook GitHub Bot do klasyfikowania zgłoszeń i pull requestów. Nowy przewodnik dla maintainerów zawiera więcej informacji o klasyfikacji i używaniu GitHub Bota. Prosimy o dodanie siebie do zespołu zgłoszeń i zachęcanie innych aktywnych członków społeczności do zrobienia tego samego!
Nowa aplikacja Skype'a jest zbudowana na React Native, co umożliwia współdzielenie jak największej ilości kodu między platformami. Aplikacja Skype'a oparta na React Native jest już dostępna w sklepach Google Play i App Store.
Podczas budowania aplikacji Skype'a w React Native przesyłamy pull requesty do głównego repozytorium React Native, aby naprawić napotkane błędy i brakujące funkcje. Dotychczas udało nam się scalić około 70 pull requestów.
React Native umożliwił nam zasilenie aplikacji Skype'a na Androida i iOS z tego samego kodu bazowego. Chcemy również użyć tego kodu do zasilenia webowej wersji Skype'a. Aby osiągnąć ten cel, zbudowaliśmy i otworzyliśmy źródła cienkiej warstwy nad React/React Native o nazwie ReactXP. ReactXP dostarcza zestaw komponentów wieloplatformowych, które mapują się na React Native dla iOS/Android oraz na react-dom dla webu. Cele ReactXP są podobne do innej biblioteki open source o nazwie React Native for Web. Krótki opis różnic w podejściu tych bibliotek znajduje się w FAQ ReactXP.
Kontynuujemy prace nad usprawnianiem i upraszczaniem doświadczeń developerskich podczas budowania aplikacji przy użyciu Shoutem.
Rozpoczęliśmy migrację naszych aplikacji na react-navigation, ale ostatecznie odłożyliśmy to do czasu wydania stabilniejszej wersji lub aż któraś z natywnych bibliotek nawigacyjnych osiągnie stabilność.
Aktualizujemy wszystkie nasze rozszerzenia i większość bibliotek open source (animation, theme, ui) do React Native 0.47.1.
Kolejna sesja odbędzie się w środę, 13 września 2017 roku. Ponieważ to dopiero nasze trzecie spotkanie, chcielibyśmy wiedzieć, czy te notatki przynoszą korzyść społeczności React Native. Zachęcamy do kontaktu na Twitterze w przypadku sugestii, jak możemy poprawić rezultaty naszych spotkań.
Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt.
Znalazłeś błąd? Zgłoś problem →
React Native jest używany w wielu miejscach w różnych aplikacjach z rodziny Facebooka, w tym w zakładce najwyższego poziomu w głównej aplikacji. W tym poście skupiamy się na bardzo widocznym produkcie – Marketplace. Jest dostępny w kilkunastu krajach i umożliwia użytkownikom odkrywanie produktów i usług oferowanych przez innych użytkowników.
W pierwszej połowie 2017 roku, dzięki wspólnym wysiłkom zespołów Relay, Marketplace, Mobile JS Platform i React Native, skróciliśmy czas do interakcji (TTI) w Marketplace o połowę na urządzeniach z Androidem klasy rocznikowej 2010-11. Facebook historycznie uznawał te urządzenia za urządzenia z Androidem niskiej klasy, które mają najwolniejsze czasy TTI na dowolnej platformie.
Typowy proces uruchamiania React Native wygląda następująco:
Uwaga: przedstawione proporcje nie są reprezentatywne i będą się różnić w zależności od konfiguracji i sposobu użycia React Native.
Najpierw inicjujemy rdzeń React Native (tzw. „Bridge”), a następnie uruchamiamy produktowy kod JavaScript, który określa, jakie natywne widoki React Native wyrenderuje w czasie przetwarzania natywnego.
Jednym z naszych wcześniejszych błędów było pozwolenie, by Systrace i CTScan napędzały nasze działania optymalizacyjne. Narzędzia te pomogły nam znaleźć wiele nisko wiszących owoców w 2016 roku, ale odkryliśmy, że zarówno Systrace, jak i CTScan nie odzwierciedlają scenariuszy produkcyjnych i nie mogą symulować warunków rzeczywistych. Proporcje czasu spędzanego w poszczególnych segmentach są często nieprawidłowe, a czasem wręcz bardzo odbiegają od rzeczywistości. W skrajnych przypadkach operacje, które powinny zająć kilka milisekund, faktycznie trwały setki lub tysiące milisekund. Mimo to CTScan pozostaje przydatny – wykrywa jedną trzecią regresji przed trafieniem do produkcji.
Na Androidzie niedoskonałości tych narzędzi przypisujemy faktowi, że 1) React Native to framework wielowątkowy, 2) Marketplace współdzieli przestrzeń z wieloma złożonymi widokami (jak Newsfeed czy inne zakładki najwyższego poziomu) oraz 3) czasy obliczeń bardzo się różnią. Dlatego w tym okresie pozwoliliśmy, by pomiary produkcyjne i szczegółowe analizy napędzały niemal wszystkie nasze decyzje i priorytety.
Instrumentacja produkcji może wydawać się prosta, ale okazała się dość złożonym procesem. Wymagała wielu cykli iteracyjnych (po 2-3 tygodnie każdy) z powodu opóźnień: od zatwierdzenia commita w gałęzi głównej, przez wypuszczenie aplikacji w Sklepie Play, po zebranie wystarczającej liczby próbek produkcyjnych dla weryfikacji. Każda iteracja obejmowała sprawdzenie dokładności naszych analiz, ich odpowiedniego poziomu szczegółowości oraz poprawnego sumowania się do całkowitego czasu. Nie mogliśmy polegać na wersjach alpha i beta, ponieważ nie reprezentują ogólnej populacji. W efekcie mozolnie zbudowaliśmy bardzo dokładny ślad produkcyjny oparty na agregacji milionów próbek.
Jednym z powodów skrupulatnego sprawdzania, czy każda milisekunda w analizach sumuje się do metryk nadrzędnych, było wczesne wykrycie luk w instrumentacji. Okazało się, że nasze wstępne analizy nie uwzględniały przestojów spowodowanych przełączaniem wątków. Same przełączania nie są kosztowne, ale przełączanie na zajęte wątki już wykonujące pracę jest bardzo kosztowne. Odtworzyliśmy te blokady lokalnie poprzez dodanie wywołań Thread.sleep() w kluczowych momentach i rozwiązaliśmy problem poprzez:
usunięcie zależności od AsyncTask,
rezygnację z wymuszonej inicjalizacji ReactContext i NativeModules w wątku UI oraz
usunięcie zależności od pomiaru ReactRootView podczas inicjalizacji.
Razem, usunięcie tych problemów z blokadą wątków skróciło czas uruchamiania o ponad 25%.
Metryki z produkcji podważyły też niektóre z naszych wcześniejszych założeń. Przykładowo, wcześniej wstępnie ładowaliśmy wiele modułów JavaScript na ścieżce startowej, zakładając, że zgrupowanie ich w jednym pakiecie zmniejszy koszt ich inicjalizacji. Jednak koszt wstępnego ładowania i grupowania tych modułów znacznie przewyższał korzyści. Poprzez rekonfigurację naszych czarnych list inline require i usunięcie modułów JavaScript ze ścieżki startowej, udało nam się uniknąć ładowania niepotrzebnych modułów, takich jak Relay Classic (gdy potrzebny był tylko Relay Modern). Dziś nasza sekcja RUN_JS_BUNDLE jest ponad 75% szybsza.
Odnaleźliśmy też korzyści badając natywne moduły specyficzne dla produktu. Przykładowo, poprzez leniwą inicjalizację zależności modułu natywnego, zmniejszyliśmy jego koszt o 98%. Usuwając rywalizację uruchamiania Marketplace z innymi produktami, skróciliśmy czas startu o równoważny przedział.
Najlepsze jest to, że wiele z tych ulepszeń ma szerokie zastosowanie na wszystkich ekranach budowanych z React Native.
Ludzie zakładają, że problemy z wydajnością startu React Native wynikają z powolnego JavaScriptu lub nadmiernie długiego czasu sieciowego. Choć przyspieszenie elementów takich jak JavaScript skróciłoby TTI w znaczącym stopniu, każdy z tych czynników stanowi znacznie mniejszy procent TTI niż wcześniej sądzono.
Dotychczasowa lekcja brzmi: mierz, mierz i jeszcze raz mierz! Niektóre korzyści płyną z przenoszenia kosztów czasu wykonania na etap budowania, jak w przypadku Relay Modern i Lazy NativeModules. Inne wynikają z unikania pracy poprzez inteligentniejsze równoległe przetwarzanie kodu lub usuwanie martwego kodu. Kolejne płyną z dużych zmian architektonicznych w React Native, jak usuwanie blokad wątków. Nie istnieje jedno wielkie rozwiązanie problemów wydajności, a długoterminowe sukcesy będą wynikać z przyrostowej instrumentacji i ulepszeń. Nie pozwól, by decyzjami kierowały uprzedzenia poznawcze. Zamiast tego, skrupulatnie zbieraj i interpretuj dane produkcyjne, aby kierować przyszłymi pracami.
Długoterminowo chcemy, aby TTI Marketplace było porównywalne z podobnymi produktami zbudowanymi natywnie, a ogólnie – by wydajność React Native dorównywała natywnej. Co więcej, chociaż w tym półroczu drastycznie zmniejszyliśmy koszt startu mostka React Native o około 80%, planujemy zbliżyć ten koszt do zera poprzez projekty takie jak Prepack i więcej przetwarzania na etapie budowania.
Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt.
Znalazłeś błąd? Zgłoś problem →
Kontynuujemy miesięczne spotkania React Native! Tym razem dołączyli do nas przedstawiciele Infinite Red, twórcy konferencji Chain React poświęconej React Native. Ponieważ większość uczestników występowała na Chain React, przełożyliśmy spotkanie o tydzień. Nagrania prelekcji zostały opublikowane online i gorąco zachęcam do ich obejrzenia. Zobaczmy, co słychać u naszych zespołów.
Mike Grabowski jak zwykle zarządza miesięcznymi wydaniami React Native, w tym kilkoma opublikowanymi wersjami beta. Szczególnie skupia się na publikacji builda v0.43.5 w npm, ponieważ to umożliwia korzystanie użytkownikom Windows!
Prace nad Haul postępują powoli, ale systematycznie. Trwa proces dodawania HMR przez pull request, a inne ulepszenia już zostały wdrożone. Ostatnio kilku liderów branży przyjęło to rozwiązanie. Prawdopodobnie planowane jest rozpoczęcie płatnej pracy na pełen etat w tym obszarze.
Przygotowujemy kilka ciekawych rzeczy z naszego działu OSS. W szczególności pracujemy nad integracją Material Palette API z React Native. Planujemy wreszcie wydać nasz natywny zestaw dla iOS, który ma zapewnić wygląd i działanie identyczne jak natywnych komponentów.
Ostatnio uruchomiliśmy Native Directory, aby ułatwić odkrywanie i ocenę bibliotek w ekosystemie React Native. Problem: mnóstwo bibliotek, trudno je przetestować, konieczne ręczne stosowanie heurystyk i nie od razu wiadomo, które są po prostu najlepsze. Trudno też stwierdzić kompatybilność z CRNA/Expo. Native Directory próbuje rozwiązać te problemy. Sprawdź i dodaj swoją bibliotekę. Lista bibliotek jest tutaj. To dopiero nasza pierwsza wersja – chcemy, by to narzędzie należało do społeczności, nie tylko do ludzi z Expo. Pomóż, jeśli uważasz to za wartościowe!
Dodaliśmy wstępne wsparcie instalacji pakietów npm w Snack z Expos SDK 19. Daj znać o problemach – wciąż pracujemy nad błędami. Razem z Native Directory ułatwi to testowanie bibliotek zależnych tylko od JS lub zawartych w Expo SDK. Przetestuj:
Kontynuujemy prace nad: audio/wideo, kamerą, gestami (ze Software Mansion, react-native-gesture-handler), integracją GL z kamerą. Planujemy wdrożenie części funkcji w SDK20 (sierpień) oraz znaczące ulepszenia innych. Rozpoczynamy też budowę infrastruktury w kliencie Expo do pracy w tle (geolokalizacja, audio, powiadomienia itp.).
Adam Miskiewicz poczynił postępy w imitacji przejść z UINavigationController w react-navigation. Zobacz wczesną wersję w jego tweecie – wkrótce premiera. Sprawdź też MaskedViewIOS, który włączył do głównego kodu. Jeśli masz umiejętności, zaimplementuj MaskedView dla Androida – byłoby świetnie!
Facebook wewnętrznie eksperymentuje z osadzaniem natywnych komponentów ComponentKit i Litho wewnątrz React Native.
Wkład w React Native jest bardzo mile widziany! Jeśli zastanawiasz się, jak możesz się przyczynić, poradnik "Jak wnosić swój wkład" opisuje nasz proces rozwojowy i przedstawia kroki do wysłania swojego pierwszego pull requesta. Istnieją również inne sposoby wniesienia wkładu, które nie wymagają pisania kodu, jak np. triaż zgłoszeń (issues) lub aktualizacja dokumentacji.
W chwili pisania React Native ma 635otwartych zgłoszeń i 249otwartych pull requestów. To przytłacza naszych maintainerów, a gdy problemy są naprawiane wewnętrznie, trudno jest upewnić się, że odpowiednie zadania są aktualizowane.
Nie jesteśmy pewni, jakie podejście byłoby najlepsze, aby to ogarnąć przy jednoczesnym zadowoleniu społeczności. Niektóre (ale nie wszystkie!) opcje obejmują zamykanie nieaktualnych zgłoszeń, nadanie znacznie większej liczbie osób uprawnień do zarządzania zgłoszeniami oraz automatyczne zamykanie zgłoszeń niespełniających szablonu. Napisaliśmy przewodnik "Czego oczekiwać od maintainerów", aby ustalić oczekiwania i uniknąć niespodzianek. Jeśli masz pomysły, jak możemy ulepszyć to doświadczenie dla maintainerów, jednocześnie zapewniając, że osoby zgłaszające problemy i pull requesty czują się wysłuchane i docenione – daj nam znać!
Zaprezentowaliśmy Designer Tool współpracujący z plikami React Native na Chain React. Wielu uczestników zapisało się na listę oczekujących.
Przyglądamy się również innym rozwiązaniom cross-platformowym jak Google Flutter (nadchodzi poważne porównanie), Kotlin Native i Apache Weex, aby zrozumieć różnice architektoniczne i co możemy się od nich nauczyć, by poprawić ogólną wydajność React Native.
Przeszliśmy na react-navigation w większości naszych aplikacji, co poprawiło ogólną wydajność.
Ogłosiliśmy również NativeBase Market – platformę z komponentami i aplikacjami React Native (dla developerów i przez developerów).
CodePush został zintegrowany z Mobile Center. Obecni użytkownicy nie zauważą zmian w swoim workflow.
Niektórzy zgłaszali problem z duplikowaniem aplikacji – mieli już aplikację w Mobile Center. Pracujemy nad rozwiązaniem, ale jeśli masz dwie aplikacje, daj nam znać, a połączymy je dla Ciebie.
Mobile Center obsługuje teraz powiadomienia push (Push Notifications) dla CodePush. Pokazaliśmy też, jak kombinacja Powiadomień i CodePush może być użyta do testów A/B aplikacji – coś unikalnego dla architektury ReactNative.
VS Code ma znany problem z debugowaniem ReactNative – następna wersja rozszerzenia, która ukaże się za kilka dni, naprawi ten błąd.
Ponieważ wiele innych zespołów w Microsoft również pracuje nad React Native, postaramy się o lepszą reprezentację wszystkich grup na następnym spotkaniu.
Zakończyliśmy proces upraszczania rozwoju React Native na Shoutem. Możesz używać wszystkich standardowych komend react-native podczas tworzenia aplikacji na Shoutem.
Włożyliśmy dużo pracy w ustalenie najlepszego podejścia do profilowania w React Native. Duża część dokumentacji jest nieaktualna, więc postaramy się przygotować pull request do oficjalnej dokumentacji lub przynajmniej opisać nasze wnioski w poście na blogu.
Przestawiamy nasze rozwiązanie nawigacyjne na react-navigation, więc wkrótce możemy podzielić się uwagami.
Wydaliśmy nowy komponent HTML w naszym zestawie narzędzi, który przekształca surowy HTML w drzewo komponentów React Native.
Rozpoczęliśmy pracę nad pull requestem do Metro Bundler z funkcjami react-native-repackager. Zaktualizowaliśmy react-native-repackager do obsługi RN 44 (którego używamy w produkcji). Wykorzystujemy go w naszej infrastrukturze mockującej dla detox.
Przez ostatnie trzy tygodnie pokrywaliśmy aplikację Wix testami detox. To niesamowite doświadczenie pokazujące, jak redukować manualne QA w aplikacji tej skali (ponad 40 inżynierów). Naprawiliśmy kilka problemów z detoxem - właśnie opublikowaliśmy nową wersję. Z przyjemnością donoszę, że spełniamy założenia "polityki zerowej flakiness" i testy konsekwentnie przechodzą.
Detox dla Androida posuwa się naprzód. Otrzymujemy znaczącą pomoc od społeczności. Spodziewamy się wstępnej wersji za około dwa tygodnie.
DetoxInstruments, nasze narzędzie do testowania wydajności, rozrosło się bardziej niż pierwotnie planowaliśmy. Planujemy przekształcić je w samodzielne narzędzie niepowiązane ściśle z detoxem. Pozwoli ono analizować wydajność aplikacji iOS w ogóle. Będzie też zintegrowane z detoxem, co umożliwi automatyzację testów metryk wydajności.
Następne spotkanie odbędzie się 16 sierpnia 2017 roku. Ponieważ to dopiero nasze drugie spotkanie, chcielibyśmy wiedzieć, czy te notatki przynoszą korzyść społeczności React Native. Zachęcamy do kontaktu na Twitterze z sugestiami, jak możemy ulepszyć rezultaty tych spotkań.
Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt.
Znalazłeś błąd? Zgłoś problem →
W Shoutem mieliśmy to szczęście, że pracujemy z React Native od samego początku. Od pierwszego dnia chcieliśmy być częścią tej niesamowitej społeczności. Dość szybko zrozumieliśmy, że niemal niemożliwe jest nadążenie za tempem jej rozwoju i ulepszeń. Dlatego postanowiliśmy zorganizować comiesięczne spotkania, na których główni współtwórcy React Native mogą krótko przedstawić swoje działania i plany.
Pierwszą sesję spotkań odbyliśmy 14 czerwca 2017. Misja miesięcznika React Native jest prosta i jasna: ulepszać społeczność React Native. Prezentowanie działań zespołów ułatwia współpracę między nimi poza spotkaniami.
Pracują nad ulepszeniem procesu wydań poprzez wykorzystanie Detox do testów E2E. Pull request powinien wkrótce zostać zaakceptowany.
Ich pull request dotyczący Blob został już scalony, kolejne są w przygotowaniu.
Zwiększają wykorzystanie Haul w projektach wewnętrznych, aby porównać jego działanie z Metro Bundler. Współpracują z zespołem webpack nad lepszą wydajnością wielowątkową.
Wewnętrznie wdrożyli lepszą infrastrukturę do zarządzania projektami open source. Planują publikować więcej w nadchodzących tygodniach.
Konferencja React Native Europe jest w przygotowaniu - na razie nic szczególnego, ale wszyscy jesteście zaproszeni!
Tymczasowo wycofali się z pracy nad react-navigation, aby zbadać alternatywy (szczególnie natywne rozwiązania nawigacyjne).
Create React Native App zostało dodane do przewodnika dla początkujących w dokumentacji. Expo zachęca autorów bibliotek do jasnego określania, czy ich biblioteka współpracuje z CRNA, a jeśli tak – do wyjaśnienia konfiguracji.
Pakowarka React Native stała się niezależnym projektem o nazwie Metro Bundler. Zespół Metro w Londynie chce lepiej odpowiadać na potrzeby społeczności, poprawić modularność dla przypadków użycia wykraczających poza React Native oraz zwiększyć responsywność w kwestiach problemów i pull requestów.
W nadchodzących miesiącach zespół React Native skupi się na udoskonalaniu API komponentów prymitywnych. Oczekujcie poprawy w zakresie niuansów układu, dostępności i typowania flow.
Zespół planuje także w tym roku poprawić modularność rdzenia poprzez refaktoryzację umożliwiającą pełne wsparcie platform stron trzecich, takich jak Windows i macOS.
Zespół pracuje nad aplikacją do projektowania UI/UX (kryptonim: Builder), która bezpośrednio współpracuje z plikami .js. Obecnie obsługuje tylko React Native. Działa podobnie jak Adobe XD i Sketch.
Pracują nad możliwością wczytania istniejącej aplikacji React Native w edytorze, wprowadzania zmian (wizualnie, jak projektant) i zapisywania zmian bezpośrednio w pliku JS.
Chcą zasypać przepaść między projektantami a developerami i połączyć ich w ramach jednego repozytorium.
Ponadto NativeBase niedawno osiągnął 5000 gwiazdek na GitHubie.
CodePush został zintegrowany z Mobile Center. To pierwszy krok w zapewnianiu lepiej zintegrowanego doświadczenia z dystrybucją, analityką i innymi usługami. Ogłoszenie dostępne jest tutaj.
W VS Code występuje błąd związany z debugowaniem – obecnie nad nim pracują i wkrótce udostępnią nowy build.
Badają możliwość użycia Detox do testów integracyjnych, analizują kontekst JSC w celu pozyskiwania zmiennych wraz z raportami awarii.
Usprawnianie pracy z aplikacjami Shoutem przy użyciu narzędzi społeczności React Native. Użytkownicy będą mogli korzystać ze wszystkich poleceń React Native do uruchamiania aplikacji tworzonych w Shoutem.
Badanie narzędzi profilujących dla React Native. Mieli wiele problemów z konfiguracją i podzielą się odkrytymi wnioskami.
Shoutem pracuje nad ułatwieniem integracji React Native z istniejącymi natywnymi aplikacjami. Udokumentują opracowany wewnętrznie koncept, aby uzyskać informacje zwrotne od społeczności.
Prace wewnętrzne nad wdrożeniem Detox w celu przeniesienia znaczących części aplikacji Wix na model "zero manualnej kontroli jakości". W efekcie Detox jest intensywnie używany w środowisku produkcyjnym przez dziesiątki developerów i szybko dojrzewa.
Prace nad dodaniem wsparcia w Metro Bundler dla nadpisywania dowolnych rozszerzeń plików podczas budowania. Zamiast tylko "ios" i "android", obsługiwane będą dowolne rozszerzenia jak "e2e" czy "detox". Planowane wykorzystanie do mockowania testów E2E. Istnieje już biblioteka react-native-repackager, obecnie trwają prace nad pull requestem.
Badanie możliwości automatyzacji testów wydajnościowych. Nowe repozytorium o nazwie DetoxInstruments. Możecie zajrzeć - rozwój odbywa się otwarcie.
Współpraca z kontrybutorem z KPN nad Detox dla Androida i obsługą rzeczywistych urządzeń.
Rozważanie koncepcji "Detox jako platformy" umożliwiającej budowanie innych narzędzi wymagających automatyzacji symulatora/urządzenia. Przykładem może być Storybook dla React Native lub pomysł Rama na testy integracyjne.
Spotkania odbywać się będą co cztery tygodnie. Następna sesja zaplanowana jest na 12 lipca 2017. Ponieważ dopiero zaczynamy tę inicjatywę, chcielibyśmy wiedzieć, jak te notatki służą społeczności React Native. Zapraszam do kontaktu na Twitterze jeśli macie sugestie, co powinniśmy poruszyć na kolejnych spotkaniach lub jak usprawnić ich rezultaty.
Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt.
Znalazłeś błąd? Zgłoś problem →
Wielu z Was już eksperymentowało z naszymi nowymi komponentami list po zapowiedzi w grupie społeczności, ale dziś oficjalnie je ogłaszamy! Koniec z ListView czy DataSource, nieaktualnymi wierszami, ignorowanymi błędami i nadmiernym zużyciem pamięci - z najnowszym kandydatem wydania React Native z marca 2017 (0.43-rc.1) możecie wybrać z nowej gamy komponentów najlepiej pasujący do Waszych potrzeb, z doskonałą wydajnością i bogatymi funkcjami od razu po wdrożeniu:
Jeśli chcesz wyświetlić dane podzielone na logiczne sekcje, być może z nagłówkami (np. w książce adresowej ułożonej alfabetycznie), a także obsłużyć różnorodne dane i renderowanie (np. widok profilu z przyciskami, edytorem treści, siatką zdjęć, siatką znajomych i listą historii), to właściwy wybór.
Stan wewnętrzny poddrzew elementów nie jest zachowywany po opuszczeniu obszaru renderowania. Upewnij się, że wszystkie dane są przechowywane w danych elementów lub zewnętrznych magazynach jak Flux, Redux czy Relay.
Te komponenty bazują na PureComponent, co oznacza że nie będą ponownie renderowane jeśli props pozostaną płytko-równe. Upewnij się, że wszystkie elementy od których zależy funkcja renderItem są przekazywane jako prop, który nie jest === po aktualizacji, inaczej interfejs może nie odświeżać zmian. Dotyczy to propa data i stanu komponentu nadrzędnego. Przykład:
<FlatList data={this.state.data} renderItem={({item})=>( <MyItem item={item} onPress={()=> this.setState(oldState=>({ selected:{ // New instance breaks `===` ...oldState.selected,// copy old data [item.key]:!oldState.selected[item.key],// toggle }, })) } selected={ !!this.state.selected[item.key]// renderItem depends on state } /> )} selected={ // Can be any prop that doesn't collide with existing props this.state.selected// A change to selected should re-render FlatList } />
Dla oszczędności pamięci i płynności przewijania, treść renderowana jest asynchronicznie poza ekranem. Może to powodować chwilowe puste miejsca przy szybkim przewijaniu. To kompromis dostosowywany do potrzeb aplikacji, nad którym aktywnie pracujemy.
Domyślnie nowe listy szukają propa key na każdym elemencie i używają go jako klucza Reacta. Alternatywnie możesz podać własną funkcję keyExtractor.
Oprócz uproszczenia API, nowe komponenty list oferują znaczną poprawę wydajności. Kluczową zaletą jest niemal stałe zużycie pamięci niezależnie od liczby wierszy. Osiąga się to poprzez "wirtualizację" elementów znajdujących się poza obszarem renderowania - są one całkowicie odmontowywane z hierarchii komponentów, co pozwala odzyskać pamięć JavaScript po komponentach Reacta oraz pamięć natywną z drzewa cieni i widoków UI. Ma to jednak konsekwencję: wewnętrzny stan komponentów nie jest zachowywany, dlatego wszelkie ważne stany muszą być przechowywane poza komponentami, np. w sklepie Relay, Redux lub Flux.
Ograniczenie obszaru renderowania zmniejsza również obciążenie Reacta i platformy natywnej (np. związane z przechodzeniem widoków). Nawet podczas renderowania milionowego elementu, nowe listy nie wymagają iteracji przez wszystkie poprzednie elementy. Możesz nawet przeskoczyć do środka listy za pomocą scrollToIndex bez nadmiernego renderowania.
Wprowadziliśmy też ulepszenia w planowaniu zadań, które poprawiają responsywność aplikacji. Elementy na granicy obszaru renderowania są przetwarzane rzadziej i z niższym priorytetem, po zakończeniu aktywnych gestów, animacji lub innych interakcji.
W przeciwieństwie do ListView, wszystkie elementy w obszarze renderowania są ponownie renderowane przy każdej zmianie właściwości (props). Zwykle nie stanowi to problemu dzięki ograniczonej liczbie widocznych elementów, ale przy skomplikowanych strukturach warto stosować najlepsze praktyki wydajnościowe Reacta: używaj React.PureComponent i/lub shouldComponentUpdate w swoich komponentach, aby ograniczyć ponowne renderowanie poddrzew.
Jeśli możesz obliczyć wysokość wierszy bez ich renderowania, podaj właściwość getItemLayout dla lepszego doświadczenia użytkownika. Umożliwi to płynniejsze przewijanie do konkretnych pozycji (np. za pomocą scrollToIndex) oraz poprawi wygląd wskaźnika przewijania, ponieważ wysokość zawartości będzie znana bez renderowania.
Do alternatywnych typów danych (np. niemutowalnych list) najlepiej użyć <VirtualizedList>. Akceptuje on właściwość getItem zwracającą dane elementu dla dowolnego indeksu i ma bardziej elastyczne typowanie Flow.
W nietypowych przypadkach możesz dostosować różne parametry: windowSize (kompromis między pamięcią a UX), maxToRenderPerBatch (dostosowanie szybkości wypełniania), onEndReachedThreshold (kontrola ładowania przy przewijaniu) i inne.
Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt.
Znalazłeś błąd? Zgłoś problem →
W Facebooku często potrzebujemy uzyskiwać dostępu do głęboko zagnieżdżonych wartości w strukturach danych pobieranych za pomocą GraphQL. Podczas uzyskiwania dostępu do tych głęboko zagnieżdżonych wartości, typowe jest występowanie jednego lub więcej pól pośrednich, które mogą przyjmować wartość null. Te pola pośrednie mogą być nullem z różnych powodów - od nieudanych kontroli prywatności po sam fakt, że null okazuje się najbardziej elastycznym sposobem reprezentowania błędów niefatalnych.
Niestety, uzyskiwanie dostępu do tych głęboko zagnieżdżonych wartości jest obecnie żmudne i rozwlekłe.
Istnieje propozycja w ECMAScript wprowadzenia operatora egzystencjalnego, co znacznie uprościłoby tę operację. Ale do czasu finalizacji tej propozycji, potrzebowaliśmy rozwiązania, które poprawi jakość naszego kodu, zachowa istniejącą semantykę języka i wspiera bezpieczeństwo typów dzięki Flow.
Stworzyliśmy w tym celu funkcję egzystencjalną, którą nazwaliśmy idx.
idx(props,_=> _.user.friends[0].friends);
Wywołanie w tym fragmencie kodu zachowuje się podobnie do wyrażenia logicznego w powyższym przykładzie, ale z znacznie mniejszą ilością powtórzeń. Funkcja idx przyjmuje dokładnie dwa argumenty:
Dowolną wartość, zazwyczaj obiekt lub tablicę, w której chcesz uzyskać dostęp do zagnieżdżonej wartości.
Funkcję, która otrzymuje pierwszy argument i uzyskuje dostęp do zagnieżdżonej wartości na nim.
Teoretycznie, funkcja idx będzie przechwytywać błędy wynikające z odwoływania się do właściwości na null lub undefined. Jeśli taki błąd zostanie przechwycony, zwróci null lub undefined. (Możesz zobaczyć, jak można to zaimplementować w idx.js.)
W praktyce przechwytywanie każdego zagnieżdżonego dostępu do właściwości jest wolne, a rozróżnianie konkretnych rodzajów błędów TypeError jest niestabilne. Aby rozwiązać te problemy, stworzyliśmy wtyczkę Babel, która przekształca powyższe wywołanie idx w następujące wyrażenie:
Na końcu dodaliśmy niestandardową deklarację typu Flow dla idx, która pozwala na prawidłowe sprawdzanie typów podczas przechodzenia w drugim argumencie, jednocześnie umożliwiając zagnieżdżony dostęp do właściwości mogących przyjmować wartość null.
Funkcja, wtyczka Babel i deklaracja Flow są teraz dostępne na GitHubie. Można ich używać instalując pakiety npm idx i babel-plugin-idx, a następnie dodając "idx" do listy wtyczek w pliku .babelrc.
Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt.
Znalazłeś błąd? Zgłoś problem →
Dziś prezentujemy Create React Native App: nowe narzędzie, które znacząco ułatwia rozpoczęcie pracy z projektem React Native! Jest ono mocno inspirowane projektem Create React App i powstało we współpracy między Facebookiem a Expo (dawniej Exponent).
Wielu programistów boryka się z instalacją i konfiguracją natywnych zależności budowania w React Native, szczególnie na Androida. Dzięki Create React Native App nie ma potrzeby używania Xcode czy Android Studio, a możesz tworzyć aplikacje na iOS nawet pracując na Linuxie lub Windowsie. Jest to możliwe dzięki aplikacji Expo, która ładuje i uruchamia projekty CRNA napisane w czystym JavaScript bez kompilacji kodu natywnego.
Wypróbuj utworzenie nowego projektu (zastąp odpowiednimi komendami yarn jeśli go używasz):
$ npm i -g create-react-native-app $ create-react-native-app my-project $ cd my-project $ npm start
Spowoduje to uruchomienie pakowacza React Native i wygenerowanie kodu QR. Otwórz go w aplikacji Expo aby załadować swój JavaScript. Wywołania console.log są przekazywane do twojego terminala. Możesz korzystać ze standardowych API React Native oraz z Expo SDK.
Wiele projektów React Native ma zależności w Javie lub Objective-C/Swift wymagające kompilacji. Aplikacja Expo zawiera API do obsługi kamery, wideo, kontaktów i innych, a także dołącza popularne biblioteki jak react-native-maps od Airbnb czy uwierzytelnianie Facebooka. Jeśli jednak potrzebujesz natywnej zależności, której Expo nie dołącza, prawdopodobnie będziesz musiał skonfigurować własny proces budowania. Podobnie jak w Create React App, CRNA obsługuje proces "wysunięcia" (ejecting).
Możesz uruchomić npm run eject aby uzyskać projekt bardzo podobny do tego generowanego przez react-native init. Od tego momentu będziesz potrzebować Xcode i/lub Android Studio, tak jak przy użyciu react-native init, dodawanie bibliotek za pomocą react-native link będzie działać, a ty zyskasz pełną kontrolę nad procesem kompilacji kodu natywnego.
Create React Native App jest już wystarczająco stabilne do powszechnego użytku, co oznacza że nie możemy się doczekać waszych opinii! Możesz znaleźć mnie na Twitterze lub zgłosić problem w repozytorium GitHub. Pull requesty są bardzo mile widziane!
Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt.
Znalazłeś błąd? Zgłoś problem →
Przez ostatni rok pracowaliśmy nad poprawą wydajności animacji wykorzystujących bibliotekę Animated. Animacje są kluczowe dla stworzenia pięknego doświadczenia użytkownika, ale mogą być trudne do poprawnego zaimplementowania. Chcemy ułatwić developerom tworzenie wydajnych animacji bez obaw, że fragmenty ich kodu spowodują opóźnienia.
API Animated zostało zaprojektowane z ważnym ograniczeniem: jest serializowalne. Oznacza to, że możemy przesłać wszystkie informacje o animacji do warstwy natywnej jeszcze przed jej rozpoczęciem, co pozwala natywnemu kodowi wykonywać animację na wątku UI bez konieczności przechodzenia przez mostek w każdej klatce. To niezwykle przydatne, ponieważ po rozpoczęciu animacji wątek JS może zostać zablokowany, a animacja nadal będzie płynnie działać. W praktyce zdarza się to często, ponieważ kod użytkownika działa na wątku JS, a renderowania Reacta również mogą blokować JS na długi czas.
Projekt rozpoczął się około roku temu, gdy Expo zbudowało aplikację li.st na Androida. Krzysztof Magiera został zatrudniony do stworzenia początkowej implementacji na Androida. Zakończyło się to sukcesem i li.st była pierwszą aplikacją korzystającą z animacji sterowanych natywnie za pomocą Animated. Kilka miesięcy później Brandon Withrow zbudował początkową implementację na iOS. Następnie Ryan Gomba i ja pracowaliśmy nad dodaniem brakujących funkcji, takich jak obsługa Animated.event, oraz naprawą błędów wykrytych podczas używania tej technologii w aplikacjach produkcyjnych. To był prawdziwie wspólnotowy wysiłek i chciałbym podziękować wszystkim zaangażowanym oraz Expo za sponsorowanie znacznej części rozwoju. Obecnie technologia jest używana przez komponenty Touchable w React Native oraz animacje nawigacyjne w nowo wydanej bibliotece React Navigation.
Najpierw przyjrzyjmy się, jak obecnie działają animacje z użyciem Animated ze sterownikiem JS. Podczas korzystania z Animated deklarujesz graf węzłów reprezentujących animacje, które chcesz wykonać, a następnie używasz sterownika do aktualizacji wartości Animated za pomocą predefiniowanej krzywej. Możesz również aktualizować wartość Animated, łącząc ją ze zdarzeniem View przy użyciu Animated.event.
Oto podział kroków animacji i miejsc ich wykonywania:
JS: Sterownik animacji używa requestAnimationFrame do wykonywania w każdej klatce i aktualizuje sterowaną wartość przy użyciu nowej wartości obliczonej na podstawie krzywej animacji.
JS: Obliczane są wartości pośrednie i przekazywane do węzła właściwości dołączonego do View.
JS: View jest aktualizowany za pomocą setNativeProps.
Mostek JS do Native.
Natywny: Aktualizowany jest UIView lub android.View.
Jak widać, większość pracy odbywa się na wątku JS. Jeśli zostanie on zablokowany, animacja będzie pomijać klatki. Dodatkowo w każdej klatce musi przechodzić przez mostek JS-Native, aby aktualizować widoki natywne.
Sterownik natywny przenosi wszystkie te kroki do warstwy natywnej. Ponieważ Animated generuje graf animowanych węzłów, może być on zserializowany i wysłany do natywnego kodu tylko raz przy rozpoczęciu animacji, eliminując potrzebę wywołań zwrotnych do wątku JS. Kod natywny może samodzielnie aktualizować widoki bezpośrednio na wątku UI w każdej klatce.
Oto przykład, jak możemy serializować wartość animowaną i węzeł interpolacji (nie jest to dokładna implementacja, tylko przykład).
Utwórz natywny węzeł wartości - to wartość, która będzie animowana:
Dzięki temu natywny moduł animacji ma wszystkie informacje potrzebne do bezpośredniej aktualizacji widoków natywnych bez konieczności odwoływania się do JS w celu obliczenia wartości.
Pozostaje tylko uruchomić animację, określając typ krzywej animacyjnej i wartość animowaną do aktualizacji. Animacje czasowe można uprościć, obliczając wcześniej w JS każdą klatkę animacji, aby zmniejszyć implementację natywną.
Natywny: Sterownik animacji natywnej używa CADisplayLink lub android.view.Choreographer, aby wykonywać się przy każdej klatce i aktualizować sterowaną wartość przy użyciu nowej wartości obliczonej na podstawie krzywej animacji.
Natywny: Obliczane są wartości pośrednie i przekazywane do węzła właściwości podpiętego do widoku natywnego.
Natywny: Aktualizowany jest UIView lub android.View.
Jak widać, brak wątku JS i brak mostu – to oznacza szybsze animacje! 🎉🎉
Animated.timing(this.state.animatedValue,{ toValue:1, duration:500, useNativeDriver:true,// <-- Add this }).start();
Wartości animowane są kompatybilne tylko z jednym sterownikiem, więc jeśli używasz sterownika natywnego przy uruchamianiu animacji na wartości, upewnij się że każda animacja tej wartości również go używa.
Działa to również z Animated.event, co jest szczególnie przydatne przy animacjach śledzących pozycję przewijania – bez sterownika natywnego zawsze działałyby z opóźnieniem jednej klatki względem gestu z powodu asynchronicznej natury React Native.
<Animated.ScrollView// <-- Use the Animated ScrollView wrapper scrollEventThrottle={1}// <-- Use 1 here to make sure no events are ever missed onScroll={Animated.event( [{ nativeEvent:{ contentOffset:{ y:this.state.animatedValue}}}], { useNativeDriver:true}// <-- Add this )} > {content} </Animated.ScrollView>
Nie wszystkie funkcje Animated są obecnie obsługiwane w Native Animated. Główne ograniczenie: można animować tylko właściwości niezwiązane z układem – działają np. transform i opacity, ale właściwości Flexbox i position już nie. Kolejne: Animated.event działa tylko z bezpośrednimi zdarzeniami, nie z propagującymi. Oznacza to, że nie współpracuje z PanResponder, ale działa np. z ScrollView#onScroll.
Native Animated jest częścią React Native od dłuższego czasu, ale nie był dokumentowany, ponieważ uznawano go za eksperymentalny. Upewnij się więc, że używasz aktualnej wersji React Native (0.40+), jeśli chcesz z tej funkcji korzystać.
Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt.
Znalazłeś błąd? Zgłoś problem →
Po opublikowaniu aplikacji w sklepach z aplikacjami, internacjonalizacja jest kolejnym krokiem do poszerzenia zasięgu odbiorców. Ponad 20 krajów i miliony ludzi na świecie używają języków pisanych od prawej do lewej (RTL). Dlatego konieczne jest zapewnienie obsługi RTL w Twojej aplikacji.
Z przyjemnością ogłaszamy, że React Native został ulepszony o obsługę układów RTL. Funkcja jest już dostępna w gałęzi głównej react-native, a pojawi się w następnym wydaniu kandydackim: v0.33.0-rc.
Wymagało to zmian w css-layout (silniku układu RN), implementacji rdzenia RN oraz konkretnych komponentów JS typu open source.
Aby przetestować obsługę RTL w środowisku produkcyjnym, najnowsza wersja aplikacji Facebook Ads Manager (pierwszej w pełni cross-platformowej aplikacji RN) jest dostępna w języku arabskim i hebrajskim z układami RTL dla iOS i Android. Oto jak wygląda w tych językach RTL:
css-layout już wykorzystuje koncepcję start i end w układzie. W trybie LTR (od lewej do prawej) start oznacza left, a end oznacza right. W RTL start oznacza right, a end oznacza left. Dzięki temu RN może polegać na obliczeniach start i end do określenia poprawnego układu, w tym position, padding i margin.
Dodatkowo, css-layout sprawia, że kierunek każdego komponentu dziedziczy po rodzicu. Oznacza to, że wystarczy ustawić kierunek głównego komponentu na RTL, aby cała aplikacja się odwróciła.
Poniższy diagram ogólnie przedstawia wprowadzone zmiany:
Aby obsługiwać układ RTL, wywołaj funkcję allowRTL() na początku natywnego kodu. Dostarczyliśmy to narzędzie, aby zastosować układ RTL tylko wtedy, gdy Twoja aplikacja jest gotowa. Przykład:
iOS:
// in AppDelegate.m [[RCTI18nUtil sharedInstance] allowRTL:YES];
Android:
// in MainActivity.java I18nUtil sharedI18nUtilInstance =I18nUtil.getInstance(); sharedI18nUtilInstance.allowRTL(context,true);
W przypadku Androida dodaj android:supportsRtl="true" do elementu <application> w pliku AndroidManifest.xml.
Teraz, po ponownej kompilacji aplikacji i zmianie języka urządzenia na język RTL (np. arabski lub hebrajski), układ aplikacji powinien automatycznie zmienić się na RTL.
Ogólnie większość komponentów jest już gotowa na RTL, np.:
Układ LTR
Układ RTL
Istnieje jednak kilka przypadków, w których będziesz potrzebować I18nManager. W I18nManager znajdziesz stałą isRTL, która informuje, czy układ aplikacji jest RTL, co pozwoli wprowadzić niezbędne zmiany.
Jeśli komponent zawiera ikony lub obrazy, będą wyświetlane tak samo w układach LTR i RTL, ponieważ RN nie odwróci źródłowego obrazu. Dlatego należy je odwrócić zgodnie z układem.
Układ LTR
Układ RTL
Dwa sposoby odwrócenia ikony zgodnie z kierunkiem:
W Androidzie i iOS przy zmianie na układ RTL gesty i animacje są odwrotne do LTR. Obecnie w RN gesty i animacje nie są obsługiwane na poziomie kodu rdzennego, ale na poziomie komponentów. Dobra wiadomość: niektóre komponenty już obsługują RTL, np. SwipeableRow i NavigationExperimental. Inne komponenty z gestami będą wymagały ręcznej obsługi RTL.
Dobrym przykładem obsługi gestów w RTL jest SwipeableRow.
Nawet po początkowym wydaniu aplikacji kompatybilnej z RTL, prawdopodobnie będziesz iterować nowe funkcje. Aby zwiększyć efektywność rozwoju, moduł I18nManager oferuje funkcję forceRTL() do szybszego testowania układu RTL bez zmiany języka na urządzeniu testowym. Możesz dodać prosty przełącznik w swojej aplikacji. Przykład z testowego komponentu RTL w RNTester:
<RNTesterBlock title={'Quickly Test RTL Layout'}> <View style={styles.flexDirectionRow}> <Text style={styles.switchRowTextView}>forceRTL</Text> <View style={styles.switchRowSwitchView}> <Switch onValueChange={this._onDirectionChange} style={styles.rightAlignStyle} value={this.state.isRTL} /> </View> </View> </RNTesterBlock>; _onDirectionChange=()=>{ I18nManager.forceRTL(!this.state.isRTL); this.setState({isRTL:!this.state.isRTL}); Alert.alert( 'Reload this page', 'Please reload this page to change the UI direction! '+ 'All examples in this app will be affected. '+ 'Check them out to see what they look like in RTL layout.', ); };
Pracując nad nową funkcją, możesz łatwo przełączyć ten przycisk i przeładować aplikację, aby zobaczyć układ RTL. Zaleta: nie musisz zmieniać ustawień języka, choć niektóre wyrównania tekstu pozostaną bez zmian (wyjaśnione w następnej sekcji). Dlatego przed wydaniem zawsze warto przetestować aplikację w języku RTL.
Obsługa RTL powinna pokryć większość UX w aplikacji, ale obecnie istnieją pewne ograniczenia:
Zachowanie wyrównania tekstu różni się w Androidzie i iOS:
W iOS domyślne wyrównanie zależy od aktywnego pakietu językowego i jest spójne. W Androidzie zależy od języka treści (angielski wyrównany do lewej, arabski do prawej).
Teoretycznie powinno to być spójne między platformami, ale użytkownicy mogą preferować różne zachowania. Wymagane są dalsze badania UX.
Brak "prawdziwej" lewej/prawej:
Jak wspomniano, mapujemy style left/right na start/end – w kodzie left staje się "prawą" na ekranie w RTL, a right "lewą". To wygodne, ale uniemożliwia określenie "prawdziwej lewej/prawej". W przyszłości może być potrzebna kontrola kierunku niezależnie od języka.
Usprawnienie obsługi gestów i animacji dla RTL:
Obecnie wciąż wymagane jest programistyczne dostosowywanie gestów i animacji pod RTL. Idealnie byłoby uprościć ten proces dla deweloperów.