Przejdź do treści głównej

Obsługa układu od prawej do lewej dla aplikacji React Native

· 7 minut czytania
Mengjue (Mandy) Wang
Stażystka inżynier oprogramowania w Facebooku
Nieoficjalne Tłumaczenie Beta

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:

Przegląd zmian w RN dla obsługi 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:

Obejmują one:

Dzięki tej aktualizacji, gdy włączysz układ RTL w aplikacji:

  • układ każdego komponentu odwróci się poziomo

  • gesty i animacje automatycznie dostosują się do RTL, jeśli używasz komponentów OSS z obsługą RTL

  • minimalny dodatkowy wysiłek może być potrzebny do pełnej obsługi RTL

Przygotowanie aplikacji do obsługi RTL

  1. Aby obsługiwać RTL, najpierw dodaj paczki językowe RTL do swojej aplikacji.

  2. 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);
  3. 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.

Tworzenie komponentów gotowych 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.

Ikony o znaczeniu kierunkowym

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:

  • Dodanie stylu transform do komponentu obrazu:

    <Image
    source={...}
    style={{transform: [{scaleX: I18nManager.isRTL ? -1 : 1}]}}
    />
  • Lub zmiana źródła obrazu w zależności od kierunku:

    let imageSource = require('./back.png');
    if (I18nManager.isRTL) {
    imageSource = require('./forward.png');
    }
    return <Image source={imageSource} />;

Gesty i animacje

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.

Przykład gestów
// SwipeableRow.js
_isSwipingExcessivelyRightFromClosedPosition(gestureState: Object): boolean {
// ...
const gestureStateDx = IS_RTL ? -gestureState.dx : gestureState.dx;
return (
this._isSwipingRightFromClosed(gestureState) &&
gestureStateDx > RIGHT_SWIPE_THRESHOLD
);
},
Przykład animacji
// SwipeableRow.js
_animateBounceBack(duration: number): void {
// ...
const swipeBounceBackDistance = IS_RTL ?
-RIGHT_SWIPE_BOUNCE_BACK_DISTANCE :
RIGHT_SWIPE_BOUNCE_BACK_DISTANCE;
this._animateTo(
-swipeBounceBackDistance,
duration,
this._animateToClosedPositionDuringBounce,
);
},

Utrzymywanie aplikacji gotowej na RTL

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.

Ograniczenia i plany na przyszłość

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.

Przetestuj sam!

Sprawdź przykład RTLExample w RNTester, aby lepiej zrozumieć obsługę RTL i daj nam znać, jak działa u Ciebie!

Dziękujemy za lekturę! Mamy nadzieję, że obsługa RTL w React Native pomoże Ci dotrzeć do międzynarodowej publiczności!

Podsumowanie spotkania w San Francisco

· 8 minut czytania
Héctor Ramos
Héctor Ramos
Former Developer Advocate @ Facebook
Nieoficjalne Tłumaczenie Beta

Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt. Znalazłeś błąd? Zgłoś problem →

W zeszłym tygodniu miałem okazję uczestniczyć w spotkaniu React Native w siedzibie Zyngi w San Francisco. Z około 200 uczestnikami było to świetne miejsce, by poznać innych programistów z mojej okolicy, którzy również interesują się React Native.

Szczególnie interesowało mnie, jak React i React Native są wykorzystywane w firmach takich jak Zynga, Netflix i Airbnb. Program wieczoru przedstawiał się następująco:

  • Szybkie prototypowanie w React

  • Projektowanie API dla React Native

  • Łączenie światów: Wykorzystanie React Native w istniejących bazach kodu

Ale najpierw wydarzenie rozpoczęło się od krótkiego wprowadzenia i podsumowania najnowszych wiadomości:

Jeśli jedno z tych spotkań odbywa się w Waszej okolicy, bardzo polecam wziąć udział!

Szybkie prototypowanie w React w Zynga

Po serii wiadomości nastąpiło krótkie wprowadzenie od Zyngi, naszego gospodarza wieczoru. Abhishek Chadha opowiedział, jak wykorzystują React do szybkiego prototypowania nowych doświadczeń mobilnych, demonstrując prototyp aplikacji podobnej do Draw Something. Stosują podejście podobne do React Native, zapewniając dostęp do natywnych API poprzez mostek. Zademonstrował to, robiąc zdjęcie publiczności aparatem urządzenia, a następnie rysując komuś kapelusz na głowie.

Projektowanie API dla React Native w Netflix

Następnie pierwszy główny wykład wieczoru. Clarence Leung, starszy inżynier oprogramowania w Netflix, przedstawił prelekcję o projektowaniu API dla React Native. Najpierw wskazał dwa główne typy bibliotek: komponenty jak paski zakładek czy selektory dat oraz biblioteki zapewniające dostęp do natywnych usług jak galeria zdjęć czy płatności w aplikacji. Przy tworzeniu biblioteki do React Native można podejść na dwa sposoby:

  • Dostarczać komponenty specyficzne dla platformy

  • Tworzyć bibliotekę wieloplatformową z podobnym API dla Androida i iOS

Każde podejście ma swoje własne uwarunkowania i to od Was zależy, co najlepiej odpowiada Waszym potrzebom.

Podejście #1

Jako przykład komponentów specyficznych dla platformy Clarence omówił DatePickerIOS i DatePickerAndroid z rdzenia React Native. W iOS selektory dat są renderowane jako część UI i łatwo je osadzić w istniejącym widoku, podczas gdy na Androidzie są prezentowane modalnie. W tym przypadku sensowne jest dostarczanie oddzielnych komponentów.

Podejście #2

Selektor zdjęć działa natomiast w podobny sposób zarówno na Androida, jak i iOS. Występują niewielkie różnice — Android na przykład nie grupuje zdjęć w foldery tak jak iOS (np. Selfie) — ale można je łatwo obsłużyć za pomocą instrukcji if i komponentu Platform.

Niezależnie od wybranego podejścia, warto minimalizować powierzchnię API i budować biblioteki dedykowane pod konkretną aplikację. Przykładowo, framework zakupów w aplikacji na iOS obsługuje jednorazowe zakupy konsumpcyjne oraz odnawialne subskrypcje. Jeśli twoja aplikacja będzie obsługiwać tylko zakupy konsumpcyjne, możesz pominąć obsługę subskrypcji w swojej bibliotece cross-platformowej.

Po prezentacji Clarence'a odbyła się krótka sesja Q&A. Jedną z ciekawostek, które się podczas niej pojawiły, była informacja, że około 80% kodu React Native napisanego dla tych bibliotek w Netflixie jest współdzielone między Androida i iOS.

Łączenie światów: React Native w istniejących bazach kodu

Ostatnią prezentację wieczoru wygłosił Leland Richardson z Airbnb. Skupiała się ona na wykorzystaniu React Native w istniejących bazach kodu. Wiedziałem już, jak łatwo napisać nową aplikację od zera w React Native, dlatego szczególnie interesowały mnie doświadczenia Airbnb z wdrażaniem React Native w ich istniejących natywnych aplikacjach.

Leland rozpoczął od rozróżnienia aplikacji greenfield i brownfield. Greenfield oznacza rozpoczęcie projektu bez konieczności uwzględniania wcześniejszej pracy. Przeciwieństwem są projekty brownfield, gdzie trzeba brać pod uwagę istniejące wymagania projektu, procesy deweloperskie i różnorodne potrzeby zespołów.

Podczas pracy nad aplikacją greenfield, CLI React Native konfiguruje jedno repozytorium dla Androida i iOS, gdzie wszystko po prostu działa. Pierwszym wyzwaniem dla wdrożenia React Native w Airbnb był fakt, że aplikacje na Androida i iOS miały osobne repozytoria. Firmy z wieloma repozytoriami muszą pokonać pewne przeszkody, zanim będą mogły zastosować React Native.

Aby rozwiązać ten problem, Airbnb najpierw utworzyło nowe repozytorium na kod React Native. Użyli serwerów CI do zlustrowania repozytoriów Androida i iOS do tego nowego repozytorium. Po uruchomieniu testów i zbudowaniu bundla, artefakty buildowe są synchronizowane z powrotem do repozytoriów Androida i iOS. To pozwala inżynierom mobilnym pracować nad natywnym kodem bez zmiany środowiska deweloperskiego. Nie muszą instalować npm, uruchamiać packagera ani pamiętać o budowaniu bundla JavaScript. Inżynierowie piszący kod React Native nie muszą martwić się synchronizacją kodu między Androidem i iOS, ponieważ pracują bezpośrednio w repozytorium React Native.

Rozwiązanie to ma jednak wady — głównie niemożność wysyłania aktualizacji atomowych. Zmiany wymagające kombinacji kodu natywnego i JavaScript wymagały trzech osobnych pull requestów, które wszystkie musiały być ostrożnie wdrażane. Aby uniknąć konfliktów, CI nie pozwalał na synchronizację zmian do repozytoriów Androida/iOS, jeśli master zmienił się podczas budowania. To powodowało długie opóźnienia w dni o wysokiej częstotliwości commitów (np. przy wydawaniu nowych wersji).

Airbnb przeszło następnie na podejście mono-repo. Na szczęście było to już rozważane, a gdy zespoły Androida i iOS oswoiły się z React Native, chętnie przyspieszyły przejście na mono-repo.

Rozwiązało to większość problemów związanych z podejściem rozdzielonych repozytoriów. Leland zauważył jednak, że powoduje to większe obciążenie serwerów kontroli wersji, co może być problemem dla mniejszych firm.

Problem nawigacji

Druga część prezentacji Lelanda skupiła się na temacie bliskim memu sercu: problemie nawigacji w React Native. Mówił o mnogości bibliotek nawigacyjnych w React Native — zarówno oficjalnych, jak i społecznościowych. Wspomniał NavigationExperimental jako rozwiązanie obiecujące, które ostatecznie nie spełniło ich oczekiwań.

W rzeczywistości żadna z istniejących bibliotek nawigacyjnych nie sprawdza się dobrze w przypadku aplikacji typu brownfield. Taka aplikacja wymaga, aby stan nawigacji był w pełni kontrolowany przez natywną aplikację. Na przykład, jeśli sesja użytkownika wygaśnie podczas prezentowania widoku React Native, natywna aplikacja powinna móc przejąć kontrolę i wyświetlić ekran logowania w razie potrzeby.

Airbnb chciało również uniknąć zastępowania natywnych pasków nawigacyjnych ich wersjami w JavaScripcie podczas przejścia, ponieważ efekt mógłby być zbyt drastyczny. Początkowo ograniczali się do widoków prezentowanych modalnie, ale to oczywiście stanowiło problem przy szerszym wdrażaniu React Native w ich aplikacjach.

Zdecydowali, że potrzebują własnej biblioteki. Biblioteka nosi nazwę airbnb-navigation. Nie została jeszcze udostępniona jako open source, ponieważ jest silnie powiązana z kodem Airbnb, ale planują jej wydanie do końca roku.

Nie będę szczegółowo omawiał API tej biblioteki, ale oto kluczowe wnioski:

  • Sceny muszą być wcześniej zarejestrowane

  • Każda scena jest wyświetlana we własnym RCTRootView. Są prezentowane natywnie na każdej platformie (np. na iOS używane są UINavigationController).

  • Główny ScrollView w scenie powinien być opakowany w komponent ScrollScene. Dzięki temu można wykorzystać natywne zachowania, jak stuknięcie w pasek stanu, aby przewinąć do góry na iOS.

  • Przejścia między scenami są obsługiwane natywnie, bez obaw o wydajność.

  • Przycisk wstecz na Androidzie jest obsługiwany automatycznie.

  • Mogą wykorzystywać stylizację paska nawigacyjnego opartą na View Controllerach poprzez bezinterfejsowy komponent Navigator.Config.

Należy też pamiętać o pewnych ograniczeniach:

  • Pasek nawigacyjny nie jest łatwo dostosowywalny w JavaScripcie, ponieważ jest komponentem natywnym. To celowe założenie, gdyż używanie natywnych pasków nawigacyjnych jest kluczowym wymogiem dla tego typu bibliotek.

  • ScreenProps muszą być serializowane/deserializowane przy przesyłaniu przez bridge, więc należy uważać przy przesyłaniu zbyt dużych ilości danych.

  • Stan nawigacji jest kontrolowany przez natywną aplikację (również kluczowy wymóg), więc rozwiązania jak Redux nie mogą manipulować stanem nawigacji.

Prezentacja Lelanda zakończyła się sesją Q&A. Ogólnie Airbnb jest zadowolone z React Native. Rozważają użycie Code Push do naprawy problemów bez przechodzenia przez App Store, a ich inżynierowie uwielbiają Live Reload, ponieważ nie muszą czekać na przebudowanie natywnej aplikacji po każdej drobnej zmianie.

Podsumowanie

Wydarzenie zakończyło się dodatkowymi informacjami o React Native:

Spotkania to świetna okazja, aby poznać innych developerów w społeczności i uczyć się od nich. Z niecierpliwością czekam na kolejne spotkania React Native. Jeśli na któreś z nich trafisz, poszukaj mnie i daj znać, jak możemy uczynić React Native jeszcze lepszym narzędziem dla Ciebie!

W kierunku lepszej dokumentacji

· 4 minuty czytania
Kevin Lacker
Kierownik Inżynierii w Facebooku
Nieoficjalne Tłumaczenie Beta

Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt. Znalazłeś błąd? Zgłoś problem →

Kluczowym elementem świetnego doświadczenia deweloperskiego jest doskonała dokumentacja. Tworzenie dobrych dokumentów wymaga wiele - idealna dokumentacja powinna być zwięzła, pomocna, dokładna, kompletna i przyjemna w odbiorze. Ostatnio intensywnie pracowaliśmy nad ulepszeniem dokumentacji w oparciu o wasze opinie i chcemy podzielić się wprowadzonymi ulepszeniami.

Przykłady w tekście

Kiedy uczysz się nowej biblioteki, języka programowania czy frameworka, następuje piękny moment, gdy po raz pierwszy piszesz fragment kodu, testujesz go, sprawdzasz czy działa... i on naprawdę działa! Stworzyłeś coś realnego. Chcieliśmy przenieść to bezpośrednie doświadczenie do naszej dokumentacji. Oto jak:

import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';

class ScratchPad extends Component {
render() {
return (
<View style={{flex: 1}}>
<Text style={{fontSize: 30, flex: 1, textAlign: 'center'}}>
Isn't this cool?
</Text>
<Text style={{fontSize: 100, flex: 1, textAlign: 'center'}}>
👍
</Text>
</View>
);
}
}

AppRegistry.registerComponent('ScratchPad', () => ScratchPad);

Uważamy, że te wbudowane przykłady, wykorzystujące moduł react-native-web-player przy wsparciu Devina Abbotta, są doskonałym sposobem na naukę podstaw React Native. Zaktualizowaliśmy nasz samouczek dla nowych deweloperów React Native, aby wszędzie tam, gdzie to możliwe, korzystał z tej funkcji. Sprawdź to - jeśli kiedykolwiek zastanawiałeś się, co się stanie, gdy zmodyfikujesz choćby najmniejszy fragment przykładowego kodu, to świetny sposób na eksperymentowanie. Ponadto, jeśli budujesz narzędzia dla deweloperów i chcesz pokazać działający przykład React Native na swojej stronie, react-native-web-player znacznie to ułatwia.

Podstawowy silnik symulacyjny pochodzi z projektu react-native-web Nicolasa Gallaghera, który umożliwia wyświetlanie komponentów React Native takich jak Text czy View w przeglądarce. Zajrzyj do react-native-web, jeśli interesuje cię budowanie doświadczeń mobilnych i webowych współdzielących znaczną część kodu.

Lepsze przewodniki

W niektórych obszarach React Native istnieje wiele sposobów osiągnięcia celu. Otrzymaliśmy sygnały, że możemy zapewnić lepsze wskazówki.

Przygotowaliśmy nowy przewodnik po nawigacji, który porównuje różne podejścia i doradza, czego użyć - Navigator, NavigatorIOS, NavigationExperimental. W średnim okresie pracujemy nad ulepszeniem i konsolidacją tych interfejsów. Na razie mamy nadzieję, że lepszy przewodnik ułatwi wam życie.

Dodaliśmy też nowy przewodnik po obsłudze dotyków, który wyjaśnia podstawy tworzenia interfejsów przypominających przyciski oraz krótko podsumowuje różne sposoby obsługi zdarzeń dotykowych.

Kolejnym obszarem, nad którym pracowaliśmy, jest Flexbox. Obejmuje to samouczki o tym, jak zarządzać układem za pomocą Flexboxa i jak kontrolować rozmiar komponentów. Znajdziesz tu także mniej efektowną, ale mamy nadzieję przydatną listę wszystkich właściwości kontrolujących układ w React Native.

Rozpoczęcie pracy

Konfiguracja środowiska deweloperskiego React Native na twoim komputerze wiąże się z szeregiem instalacji i ustawień. Trudno sprawić, by instalacja była naprawdę ekscytującym doświadczeniem, ale przynajmniej możemy uczynić ją szybką i bezbolesną.

Stworzyliśmy nowy proces rozpoczynania pracy, który pozwala wybrać system operacyjny deweloperski i mobilny na początku, zapewniając jedno zwięzłe miejsce ze wszystkimi instrukcjami konfiguracyjnymi. Przetestowaliśmy też proces instalacji, aby upewnić się, że wszystko działa i że każdy punkt decyzyjny ma jasną rekomendację. Po przetestowaniu na naszych niczego niespodziewających się współpracownikach jesteśmy pewni, że to ulepszenie.

Pracowaliśmy także nad przewodnikiem dotyczącym integracji React Native z istniejącą aplikacją. Wiele dużych aplikacji korzystających z React Native, jak np. aplikacja Facebooka, w rzeczywistości łączy fragmenty napisane w React Native z częściami stworzonymi przy użyciu standardowych narzędzi. Mamy nadzieję, że ten przewodnik ułatwi więcej osobom budowanie aplikacji w ten sposób.

Potrzebujemy Waszej pomocy

Wasze opinie pomagają nam ustalić priorytety. Wiem, że niektórzy czytając ten wpis pomyślą: "Lepsza dokumentacja? Pffft. Dokumentacja X nadal jest beznadziejna!". To świetnie – potrzebujemy tej energii. Najlepszy sposób przekazania nam opinii zależy od jej rodzaju.

Jeśli znajdziesz błąd w dokumentacji, np. nieprecyzyjny opis lub kod, który nie działa, zgłoś issue. Otaguj go jako "Documentation", aby łatwiej było przekierować go do odpowiednich osób.

Jeśli nie ma konkretnego błędu, ale coś w dokumentacji jest zasadniczo mylące, GitHub Issues nie jest najlepszym miejscem. Zamiast tego opublikuj prośbę na Canny dotyczącą obszaru dokumentacji wymagającego poprawy. Pomaga nam to ustalać priorytety przy pracach takich jak tworzenie przewodników.

Dzięki, że dotarliście tak daleko, i dziękujemy za używanie React Native!

React Native: Rok w przeglądzie

· 2 minuty czytania
Martin Konicek
Inżynier Oprogramowania w Facebooku
Nieoficjalne Tłumaczenie Beta

Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt. Znalazłeś błąd? Zgłoś problem →

Minął rok, odkąd udostępniliśmy React Native jako projekt open source. To, co zaczęło się jako pomysł garstki inżynierów, dziś jest frameworkiem używanym przez zespoły produktowe w Facebooku i poza nim. Podczas konferencji F8 ogłosiliśmy, że Microsoft wprowadza React Native do ekosystemu Windows, dając developerom możliwość budowania aplikacji na PC, telefony i Xbox. Dostarczą także open source'owe narzędzia i usługi, jak rozszerzenie React Native dla Visual Studio Code i CodePush, aby ułatwić tworzenie aplikacji na platformie Windows. Dodatkowo Samsung buduje React Native dla swojej platformy hybrydowej, co pozwoli programistom tworzyć aplikacje dla milionów SmartTV, urządzeń mobilnych i wearable. Wydaliśmy też Facebook SDK dla React Native, ułatwiając integrację funkcji społecznościowych jak Login, Sharing, App Analytics i Graph API. W ciągu roku React Native zmienił sposób budowania aplikacji na każdej większej platformie.

To była epicka podróż – ale dopiero zaczynamy. Oto spojrzenie wstecz na rozwój React Native od czasu open source'owania, wyzwania, które napotkaliśmy, oraz nasze oczekiwania na przyszłość.

To fragment artykułu. Całość przeczytasz na Facebook Code.

Zanurkuj w wydajności React Native

· 2 minuty czytania
Pieter De Baets
Inżynier oprogramowania w Facebooku
Nieoficjalne Tłumaczenie Beta

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 pozwala tworzyć aplikacje na Androida i iOS w JavaScript przy użyciu deklaratywnego modelu programowania Reacta i Relay. To prowadzi do bardziej zwięzłego, łatwiejszego w zrozumieniu kodu; szybkiej iteracji bez cyklu kompilacji; oraz łatwego współdzielenia kodu na wielu platformach. Możesz wydawać aplikacje szybciej i skupić się na istotnych szczegółach, dzięki czemu twoja aplikacja wygląda i działa fantastycznie. Optymalizacja wydajności jest tego ważną częścią. Oto historia o tym, jak sprawiliśmy, że uruchamianie aplikacji React Native stało się dwukrotnie szybsze.

Po co się spieszyć?

Gdy aplikacja działa szybciej, treści ładują się błyskawicznie, co oznacza, że użytkownicy mają więcej czasu na interakcję, a płynne animacje sprawiają, że korzystanie jest przyjemnością. Na rynkach wschodzących, gdzie dominują telefony klasy 2011 na sieciach 2G, skupienie na wydajności może zdecydować, czy aplikacja jest użyteczna, czy nie.

Od premiery React Native na iOS i Androida, stale poprawiamy wydajność przewijania list, efektywność pamięciową, responsywność interfejsu oraz czas uruchamiania aplikacji. Start aplikacji tworzy pierwsze wrażenie i testuje wszystkie elementy frameworka, dlatego jest najbardziej satysfakcjonującym i wymagającym wyzwaniem.

To jest fragment. Przeczytaj resztę posta na Facebook Code.

Wprowadzenie do Hot Reloading

· 8 minut czytania
Martín Bigio
Inżynier Oprogramowania w Instagramie
Nieoficjalne Tłumaczenie Beta

Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt. Znalazłeś błąd? Zgłoś problem →

Celem React Native jest zapewnienie najlepszego możliwego doświadczenia deweloperskiego. Kluczowym elementem jest czas między zapisaniem pliku a możliwością zobaczenia zmian. Naszym celem jest skrócenie tej pętli sprzężenia zwrotnego do poniżej 1 sekundy, nawet w miarę rozrastania się aplikacji.

Zbliżyliśmy się do tego ideału dzięki trzem głównym funkcjom:

  • Wykorzystanie JavaScriptu jako języka, który nie wymaga długiego czasu kompilacji.

  • Wdrożenie narzędzia zwanego Packager, które przekształca pliki es6/flow/jsx w zwykły JavaScript zrozumiały dla maszyny wirtualnej. Zaprojektowano je jako serwer przechowujący stan pośredni w pamięci, co umożliwia szybkie zmiany przyrostowe i wykorzystuje wiele rdzeni.

  • Stworzenie funkcji Live Reload, która przeładowuje aplikację przy zapisie.

W tym momencie wąskim gardłem nie jest już czas przeładowania aplikacji, ale utrata jej stanu. Typowym scenariuszem jest praca nad funkcją znajdującą się kilka ekranów dalej od ekranu startowego. Przy każdym przeładowaniu musisz klikać tę samą ścieżkę wielokrotnie, by wrócić do swojej funkcji, co wydłuża cykl do kilku sekund.

Hot Reloading

Idea Hot Reloading polega na utrzymywaniu działania aplikacji i wstrzykiwaniu nowych wersji edytowanych plików podczas działania programu. Dzięki temu nie tracisz stanu aplikacji, co jest szczególnie przydatne przy dopracowywania interfejsu.

Jeden film wart jest tysiąca słów. Zobacz różnicę między Live Reload (obecne) a Hot Reload (nowe).

Jeśli przyjrzysz się uważnie, zauważysz że możliwe jest odzyskanie się po czerwonym boksie błędów oraz importowanie modułów, które wcześniej nie istniały, bez konieczności pełnego przeładowania.

Ostrzeżenie: ponieważ JavaScript jest językiem silnie stanowym, Hot Reloading nie może być zaimplementowany idealnie. W praktyce obecne rozwiązanie sprawdza się dobrze w większości typowych przypadków, a pełne przeładowanie zawsze jest dostępne na wypadek problemów.

Hot Reloading dostępny jest od wersji 0.22. Możesz go włączyć:

  • Otwórz menu deweloperskie

  • Dotknij "Włącz Hot Reloading"

Implementacja w pigułce

Skoro wiemy już po co to i jak używać, czas na najciekawszą część: jak to właściwie działa.

Hot Reloading bazuje na funkcji Hot Module Replacement (HMR). Została ona wprowadzona przez webpack, a my zaimplementowaliśmy ją w React Native Packager. HMR sprawia, że Packager obserwuje zmiany plików i wysyła aktualizacje HMR do lekkiego środowiska uruchomieniowego HMR w aplikacji.

W skrócie, aktualizacja HMR zawiera nowy kod zmienionych modułów JS. Gdy środowisko uruchomieniowe je otrzyma, zastępuje stary kod modułów nowym:

Aktualizacja HMR zawiera nieco więcej niż tylko kod modułu, który chcemy zmienić, ponieważ samo zastąpienie kodu nie wystarczy, by środowisko uruchomieniowe uwzględniło zmiany. Problem w tym, że system modułów mógł już zapisać w pamięci podręcznej eksporty modułu, który aktualizujemy. Przykładowo, rozważ aplikację z dwóch modułów:

// log.js
function log(message) {
const time = require('./time');
console.log(`[${time()}] ${message}`);
}

module.exports = log;
// time.js
function time() {
return new Date().getTime();
}

module.exports = time;

Moduł log wypisuje podaną wiadomość wraz z aktualną datą dostarczoną przez moduł time.

Gdy aplikacja jest bundle'owana, React Native rejestruje każdy moduł w systemie modułów za pomocą funkcji __d. Dla tej aplikacji, pośród wielu definicji __d, będzie jedna dla log:

__d('log', function() {
... // module's code
});

To wywołanie opakowuje kod każdego modułu w anonimową funkcję, którą powszechnie nazywamy funkcją fabryczną. System modułowy śledzi funkcję fabryczną każdego modułu, czy została już wykonana oraz wynik tego wykonania (eksporty). Gdy moduł jest wymagany, system modułowy albo dostarcza buforowane eksporty, albo wykonuje funkcję fabryczną modułu po raz pierwszy i zapisuje wynik.

Załóżmy, że uruchamiasz aplikację i wymagasz modułu log. W tym momencie żadna funkcja fabryczna log ani time nie została jeszcze wykonana, więc żadne eksporty nie są buforowane. Następnie użytkownik modyfikuje time, aby zwracał datę w formacie MM/DD:

// time.js
function bar() {
const date = new Date();
return `${date.getMonth() + 1}/${date.getDate()}`;
}

module.exports = bar;

Packager wyśle nowy kod time do środowiska wykonawczego (krok 1). Gdy log zostanie ostatecznie wymagany, wyeksportowana funkcja zostanie wykonana z uwzględnieniem zmian w time (krok 2):

Teraz załóżmy, że kod log wymaga time jako zależności najwyższego poziomu:

const time = require('./time'); // top level require

// log.js
function log(message) {
console.log(`[${time()}] ${message}`);
}

module.exports = log;

Gdy log jest wymagany, środowisko wykonawcze zbuforuje jego eksporty oraz eksporty time (krok 1). Jeśli time zostanie zmodyfikowany, proces HMR nie może zakończyć się po prostu zastąpieniem kodu time. Gdyby tak zrobił, wykonanie log korzystałoby z buforowanej kopii time (starego kodu).

Aby log uwzględnił zmiany w time, musimy wyczyścić jego buforowane eksporty, ponieważ jeden z modułów od których zależy został "gorąco zamieniony" (krok 3). Gdy log zostanie ponownie wymagany, jego funkcja fabryczna zostanie wykonana, wymagając time i pobierając jego nowy kod.

API HMR

HMR w React Native rozszerza system modułów poprzez wprowadzenie obiektu hot. To API opiera się na webpackowym rozwiązaniu. Obiekt hot udostępnia funkcję accept pozwalającą zdefiniować callback wykonywany przy wymianie modułu. Np. jeśli zmienimy kod time jak poniżej, po każdej modyfikacji zobaczymy "time changed" w konsoli:

// time.js
function time() {
... // new code
}

module.hot.accept(() => {
console.log('time changed');
});

module.exports = time;

Uwaga: tylko w rzadkich przypadkach będziesz musiał ręcznie używać tego API. Gorące przeładowanie powinno działać "out of the box" w większości typowych scenariuszy.

Środowisko wykonawcze HMR

Jak widzieliśmy, czasem samo zaakceptowanie aktualizacji HMR nie wystarczy, ponieważ moduł używający zamienianego komponentu mógł zostać już wykonany z buforowanymi importami. Np. załóżmy, że drzewo zależności w aplikacji filmowej zawiera nadrzędny MovieRouter zależny od widoków MovieSearch i MovieScreen, które zależą od modułów log i time z poprzednich przykładów:

Jeśli użytkownik odwiedzi widok wyszukiwania filmów, ale nie drugi widok, wszystkie moduły oprócz MovieScreen będą miały buforowane eksporty. Przy zmianie w module time, środowisko wykonawcze musi wyczyścić eksporty log by uwzględniło zmiany w time. Proces się tu nie kończy: środowisko rekursywnie powtórzy tę operację aż do zaakceptowania wszystkich modułów nadrzędnych. Pobierze moduły zależne od log i spróbuje je zaakceptować. Dla MovieScreen może przerwać (nie był jeszcze wymagany). Dla MovieSearch wyczyści eksporty i rekursywnie przetworzy jego moduły nadrzędne. Na koniec zrobi to samo dla MovieRouter i zakończy proces (żaden moduł od niego nie zależy).

Aby przejść drzewo zależności, środowisko wykonawcze otrzymuje od Packagera odwrotne drzewo zależności w aktualizacji HMR. Dla tego przykładu środowisko otrzyma obiekt JSON:

{
modules: [
{
name: 'time',
code: /* time's new code */
}
],
inverseDependencies: {
MovieRouter: [],
MovieScreen: ['MovieRouter'],
MovieSearch: ['MovieRouter'],
log: ['MovieScreen', 'MovieSearch'],
time: ['log'],
}
}

Komponenty Reacta

Komponenty React są trudniejsze w obsłudze przy Hot Reloadingu. Problem polega na tym, że nie możemy po prostu zastąpić starego kodu nowym, ponieważ stracilibyśmy stan komponentu. W przypadku aplikacji webowych React, Dan Abramov zaimplementował transformację Babel, która wykorzystuje API HMR webpacka. W skrócie, jego rozwiązanie działa poprzez tworzenie proxy dla każdego komponentu React w czasie transformacji. Te proxy przechowują stan komponentu i delegują metody cyklu życia do właściwych komponentów, które podlegają hot reloadowaniu:

Oprócz tworzenia proxy, transformacja definiuje funkcję accept z kodem wymuszającym ponowne renderowanie komponentu przez React. Dzięki temu możemy aktualizować kod renderowania bez utraty stanu aplikacji.

Domyślny transformer w React Native używa babel-preset-react-native, który jest skonfigurowany do wykorzystania react-transform w taki sam sposób, jak w projektach webowych React z webpackiem.

Store Reduxa

Aby włączyć Hot Reloading w store'ach Reduxa, wystarczy użyć API HMR podobnie jak w projektach webowych z webpackiem:

// configureStore.js
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import reducer from '../reducers';

export default function configureStore(initialState) {
const store = createStore(
reducer,
initialState,
applyMiddleware(thunk),
);

if (module.hot) {
module.hot.accept(() => {
const nextRootReducer = require('../reducers/index').default;
store.replaceReducer(nextRootReducer);
});
}

return store;
};

Gdy zmienisz reducer, kod akceptujący tę zmianę zostanie wysłany do klienta. Klient zorientuje się, że reducer nie wie jak sam siebie zaakceptować, więc poszczy moduły, które się do niego odwołują i spróbuje je zaakceptować. Ostatecznie proces dotrze do pojedynczego store'a - modułu configureStore, który zaakceptuje aktualizację HMR.

Podsumowanie

Jeśli chcesz pomóc w ulepszaniu Hot Reloadingu, zachęcam do przeczytania postu Dana Abramova o przyszłości tej funkcji oraz do kontrybucji. Przykładowo, Johny Days pracuje nad wsparciem wielu połączonych klientów. Polegamy na was wszystkich w utrzymaniu i rozwijaniu tej funkcji.

Dzięki React Native mamy okazję przemyśleć sposób budowania aplikacji, aby zapewnić świetne doświadczenia deweloperskie. Hot Reloading to tylko jeden element układanki - jakie inne kreatywne rozwiązania możemy wdrożyć, żeby było jeszcze lepiej?

Tworzenie dostępnych aplikacji React Native

· 2 minuty czytania
Georgiy Kassabli
Inżynier oprogramowania w Facebooku
Nieoficjalne Tłumaczenie Beta

Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt. Znalazłeś błąd? Zgłoś problem →

Dzięki niedawnym premiom Reacta na webie i React Native na urządzeniach mobilnych, dostarczamy programistom nową bibliotekę do tworzenia produktów. Kluczowym aspektem budowania solidnych aplikacji jest zapewnienie, że może z nich korzystać każdy – w tym osoby z dysfunkcjami wzroku lub innymi niepełnosprawnościami. Accessibility API dla Reacta i React Native pozwala dostosować aplikacje dla użytkowników wspomagających się technologiami asystującymi, takimi jak czytniki ekranu dla osób niewidomych i niedowidzących.

W tym wpisie skupimy się na aplikacjach React Native. Zaprojektowaliśmy Accessibility API dla Reacta tak, by działało i wyglądało podobnie do rozwiązań z Androida i iOS. Jeśli tworzyłeś już dostępne aplikacje na Androida, iOSa czy web, framework i nomenklatura React AX API będą ci znajome. Przykładowo, możesz oznaczyć element interfejsu jako accessible (czyli dostępny dla technologii asystujących) i użyć accessibilityLabel do podania tekstowego opisu elementu:

<View accessible={true} accessibilityLabel=”This is simple view”>

Przeanalizujmy nieco bardziej złożone zastosowanie React AX API na przykładzie flagowego produktu Facebooka napędzanego Reactem: aplikacji Ads Manager.

To jest fragment wpisu. Przeczytaj całość na Facebook Code.

React Native dla Androida: jak stworzyliśmy pierwszą wieloplatformową aplikację w React Native

· 2 minuty czytania
Inżynier oprogramowania w Facebooku
Nieoficjalne Tłumaczenie Beta

Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt. Znalazłeś błąd? Zgłoś problem →

Wcześniej w tym roku przedstawiliśmy React Native dla iOS. React Native przenosi to, co programiści znają z Reacta na webie — deklaratywne, samodzielne komponenty UI i szybkie cykle rozwoju — na platformy mobilne, zachowując jednocześnie szybkość, wierność i wrażenia typowe dla natywnych aplikacji. Dziś z przyjemnością udostępniamy React Native dla Androida.

W Facebooku używamy React Native w środowisku produkcyjnym od ponad roku. Niemal dokładnie rok temu nasz zespół rozpoczął pracę nad aplikacją Ads Manager. Naszym celem było stworzenie nowej aplikacji, która pozwoli milionom osób reklamującym się na Facebooku zarządzać kontami i tworzyć nowe reklamy w podróży. Okazała się ona nie tylko pierwszą w pełni napisaną w React Native aplikacją Facebooka, ale też pierwszą wieloplatformową. W tym poście chcemy podzielić się z Wami, jak ją zbudowaliśmy, jak React Native umożliwił nam szybsze działanie oraz jakie wnioski wyciągnęliśmy.

To fragment. Przeczytaj resztę wpisu na Facebook Code.

React Native: Przenosimy nowoczesne techniki webowe na urządzenia mobilne

· 2 minuty czytania
Tom Occhino
Kierownik ds. Inżynierii w Facebooku
Nieoficjalne Tłumaczenie Beta

Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt. Znalazłeś błąd? Zgłoś problem →

Przedstawiliśmy React światu dwa lata temu i od tego czasu obserwowaliśmy imponujący wzrost jego popularności, zarówno wewnątrz Facebooka, jak i poza nim. Dziś, mimo że nikt nie jest zmuszony do jego używania, nowe projekty webowe w Facebooku powszechnie powstają z wykorzystaniem Reacta w różnych formach, a framework ten zdobywa szerokie uznanie w całej branży. Inżynierowie codziennie wybierają React, ponieważ pozwala im skupić więcej uwagi na produktach, a mniej na walce z frameworkiem. Dopiero po dłuższym czasie budowania z Reactem zaczęliśmy rozumieć, co czyni go tak potężnym narzędziem.

React zmusza nas do rozbijania aplikacji na odrębne komponenty, z których każdy reprezentuje pojedynczy widok. Dzięki tym komponentom łatwiej iterować nad naszymi produktami – nie musimy trzymać całego systemu w głowie, aby wprowadzić zmiany w jednej jego części. Co ważniejsze, React zastępuje mutacyjne, imperatywne API DOM deklaratywnym podejściem, podnosząc poziom abstrakcji i upraszczając model programowania. Odkryliśmy, że budując z Reactem, nasz kod staje się znacznie bardziej przewidywalny. Ta przewidywalność pozwala nam iterować szybciej i z większą pewnością, a nasze aplikacje stają się dzięki temu znacznie bardziej niezawodne. Co więcej, nie tylko łatwiej skalować aplikacje zbudowane w React, ale również odkryliśmy, że łatwiej skalować wielkość samych zespołów.

W połączeniu z szybkim cyklem iteracji w środowisku webowym, zbudowaliśmy z Reactem wspaniałe produkty, w tym wiele komponentów Facebook.com. Stworzyliśmy także niesamowite frameworki w JavaScripcie bazujące na React, jak Relay, który pozwala nam znacznie uprościć pobieranie danych na dużą skalę. Oczywiście, środowisko webowe to tylko część historii. Facebook posiada także szeroko używane aplikacje na Androida i iOS, zbudowane na rozłącznych, własnych stosach technologicznych. Konieczność budowania aplikacji na wielu platformach podzieliła naszą organizację inżynieryjną, ale to tylko jeden z czynników utrudniających natywny rozwój aplikacji mobilnych.

To jest fragment. Przeczytaj resztę wpisu na Facebook Code.