Przejdź do treści głównej

Poznaj Button, szybsze instalacje z Yarn oraz publiczny plan rozwoju

· 3 minuty 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 →

Wiele osób zgłaszało, że przy ogromie prac wokół React Native trudno śledzić wszystkie zmiany. Aby lepiej komunikować bieżące działania, publikujemy teraz plan rozwoju React Native. W skrócie prace skupiają się na trzech priorytetach:

  • Biblioteki podstawowe. Rozszerzanie funkcjonalności kluczowych komponentów i API.

  • Stabilność. Usprawnianie infrastruktury bazowej w celu redukcji błędów i poprawy jakości kodu.

  • Doświadczenie deweloperskie. Przyspieszanie pracy programistów React Native.

Jeśli masz sugestie dotyczące funkcji, które Twoim zdaniem powinny znaleźć się w planie, odwiedź Canny, gdzie możesz proponować nowe funkcje i dyskutować o istniejących pomysłach.

Nowości w React Native

Wersja 0.37 React Native, wydana dziś, wprowadza nowy podstawowy komponent ułatwiający dodawanie przycisku w każdej aplikacji. Dodajemy również obsługę nowego menedżera pakietów Yarn, który znacząco przyspiesza aktualizację zależności aplikacji.

Poznaj Button

Dziś prezentujemy podstawowy komponent <Button />, który świetnie prezentuje się na każdej platformie. To odpowiedź na jedno z najczęstszych uwag: React Native to jedno z niewielu narzędzi do tworzenia aplikacji mobilnych bez gotowego do użycia przycisku.

Prosty przycisk na Androidzie i iOS

<Button
onPress={onPressMe}
title="Press Me"
accessibilityLabel="Learn more about this Simple Button"
/>

Doświadczeni deweloperzy React Native wiedzą, jak stworzyć przycisk: użyć TouchableOpacity dla domyślnego wyglądu na iOS, TouchableNativeFeedback dla efektu falowania na Androidzie, a następnie dodać kilka stylów. Tworzenie własnych przycisków nie jest szczególnie trudne, ale naszym celem jest maksymalne uproszczenie nauki React Native. Dzięki dodaniu podstawowego przycisku do rdzenia frameworka, nowi użytkownicy będą mogli szybko tworzyć imponujące rzeczy, zamiast tracić czas na formatowanie przycisku i poznawanie niuansów komponentów dotykowych.

Button ma działać perfekcyjnie i wyglądać natywnie na każdej platformie, więc nie obsługuje wszystkich zaawansowanych funkcji niestandardowych przycisków. To doskonały punkt startowy, ale nie zamierzamy nim zastępować wszystkich istniejących rozwiązań. Więcej informacji znajdziesz w nowej dokumentacji Button, zawierającej działający przykład!

Przyspiesz react-native init za pomocą Yarn

Możesz teraz używać Yarn, nowego menedżera pakietów JavaScript, aby znacząco przyspieszyć react-native init. Aby skorzystać z przyspieszenia, zainstaluj yarn i zaktualizuj react-native-cli do wersji 1.2.0:

$ npm install -g react-native-cli

Podczas konfigurowania nowych aplikacji powinien pojawić się komunikat "Using yarn":

Korzystanie z yarn

W prostych testach lokalnych react-native init kończył się w około minutę przy dobrym połączeniu (w porównaniu do ~3 minut przy użyciu npm 3.10.8). Instalacja yarn jest opcjonalna, ale zdecydowanie zalecana.

Podziękowania

Dziękujemy wszystkim, którzy przyczynili się do tej wersji. Pełne informacje o wydaniu są dostępne na GitHubie. Dzięki ponad dwudziestu poprawkom błędów i nowym funkcjom, React Native staje się coraz lepszy dzięki Wam.

0.36: Headless JS, API klawiatury i więcej

· 3 minuty 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 →

Dziś wydajemy React Native 0.36. Czytaj dalej, aby dowiedzieć się więcej o nowościach.

Headless JS

Headless JS to sposób na uruchamianie zadań w JavaScript, gdy aplikacja działa w tle. Może być używany np. do synchronizacji świeżych danych, obsługi powiadomień push lub odtwarzania muzyki. Na razie dostępny jest tylko na Androida.

Aby rozpocząć, zdefiniuj swoje zadanie asynchroniczne w dedykowanym pliku (np. SomeTaskName.js):

module.exports = async taskData => {
// Perform your task here.
};

Następnie zarejestruj zadanie w AppRegistry:

AppRegistry.registerHeadlessTask('SomeTaskName', () =>
require('SomeTaskName'),
);

Użycie Headless JS wymaga napisania natywnego kodu Java, aby umożliwić uruchomienie usługi w razie potrzeby. Zajrzyj do naszej nowej dokumentacji Headless JS, aby dowiedzieć się więcej!

API klawiatury

Praca z klawiaturą ekranową jest teraz łatwiejsza dzięki Keyboard. Możesz teraz nasłuchiwać natywnych zdarzeń klawiatury i na nie reagować. Na przykład, aby zamknąć aktywną klawiaturę, wystarczy wywołać Keyboard.dismiss():

import {Keyboard} from 'react-native';

// Hide that keyboard!
Keyboard.dismiss();

Dzielenie animowanych wartości

Łączenie dwóch animowanych wartości przez dodawanie, mnożenie i modulo było już obsługiwane w React Native. W wersji 0.36 dodano możliwość dzielenia animowanych wartości. Są przypadki, gdy animowana wartość musi odwrócić inną animowaną wartość do obliczeń. Przykładem jest odwrócenie skali (2x --> 0.5x):

const a = Animated.Value(1);
const b = Animated.divide(1, a);

Animated.spring(a, {
toValue: 2,
}).start();

Wtedy b będzie podążać za animacją sprężynową a i generować wartość 1 / a.

Podstawowe użycie wygląda tak:

<Animated.View style={{transform: [{scale: a}]}}>
<Animated.Image style={{transform: [{scale: b}]}} />
<Animated.View>

W tym przykładzie wewnętrzny obraz w ogóle się nie rozciągnie, ponieważ skalowanie rodzica zostaje skompensowane. Jeśli chcesz dowiedzieć się więcej, sprawdź przewodnik po animacjach.

Ciemne paski statusu

Do StatusBar dodano nową wartość barStyle: dark-content. Dzięki temu możesz teraz używać barStyle zarówno na Androidzie, jak i iOS. Zachowanie będzie teraz następujące:

  • default: Użyj domyślnych ustawień platformy (jasny na iOS, ciemny na Androidzie).

  • light-content: Użyj jasnego paska statusu z czarnym tekstem i ikonami.

  • dark-content: Użyj ciemnego paska statusu z białym tekstem i ikonami.

...i więcej

To tylko próbka zmian w wersji 0.36. Sprawdź informacje o wydaniu na GitHubie, aby zobaczyć pełną listę nowych funkcji, poprawek błędów i zmian łamiących kompatybilność.

Możesz zaktualizować do wersji 0.36, uruchamiając następujące polecenia w terminalu:

$ npm install --save react-native@0.36
$ react-native upgrade

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.