Przejdź do treści głównej

33 posty z tagiem "engineering"

Zobacz wszystkie tagi

Przygotowanie aplikacji na iOS 15 i Android 12

· 3 minuty czytania
Samuel Susla
Samuel Susla
Software Engineer @ Meta
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 →

Cześć wszystkim!

Przed nadchodzącymi jesiennymi premierami nowych wersji systemów mobilnych zalecamy wcześniejsze przygotowanie aplikacji React Native, aby uniknąć problemów po ich oficjalnym udostępnieniu.

Przedstawiamy nowe WebView dla iOS

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

Od dłuższego czasu Apple odradza używanie UIWebView na rzecz WKWebView. W iOS 12, który zostanie wydany w nadchodzących miesiącach, UIWebView zostanie oficjalnie oznaczony jako przestarzały. Implementacja WebView dla iOS w React Native w dużej mierze opiera się na klasie UIWebView. Dlatego w świetle tych zmian stworzyliśmy nowy natywny backend dla iOS dla komponentu WebView w React Native, który wykorzystuje WKWebView.

Końcowe zmiany zostały wprowadzone w tym commicie i będą dostępne w wersji 0.57.

Aby skorzystać z tej nowej implementacji, użyj właściwości useWebKit:

<WebView
useWebKit={true}
source={{url: 'https://www.google.com'}}
/>

Ulepszenia

UIWebView nie posiadał prawidłowego sposobu na ułatwienie komunikacji między JavaScript działającym w WebView a React Native. Gdy wiadomości były wysyłane z WebView, polegaliśmy na obejściu, aby dostarczyć je do React Native. W skrócie, kodowaliśmy dane wiadomości w adresie URL ze specjalnym schematem i przekierowywaliśmy WebView pod ten adres. Po stronie natywnej przechwytywaliśmy i anulowaliśmy to przekierowanie, przetwarzaliśmy dane z adresu URL i w końcu wywoływaliśmy React Native. Ta implementacja była podatna na błędy i niebezpieczna. Z przyjemnością ogłaszam, że wykorzystaliśmy funkcje WKWebView, aby całkowicie ją zastąpić.

Inne zalety WKWebView w porównaniu z UIWebView to szybsze wykonywanie kodu JavaScript oraz architektura wieloprocesowa. Więcej szczegółów znajdziesz w WWDC 2014.

Ograniczenia

Jeśli twoje komponenty używają poniższych właściwości, możesz napotkać problemy podczas przełączania się na WKWebView. Na razie sugerujemy unikanie używania tych właściwości:

Niespójne zachowanie:

automaticallyAdjustContentInsets i contentInsets (commit)

Gdy dodasz contentInsets do WKWebView, nie zmienia to viewportu WKWebView. Viewport pozostaje tej samej wielkości co ramka. W przypadku UIWebView rozmiar viewportu faktycznie się zmienia (zmniejsza się, jeśli contentInsets są dodatnie).

backgroundColor (commit)

W nowej implementacji WebView dla iOS istnieje możliwość, że kolor tła będzie migać, jeśli użyjesz tej właściwości. Ponadto WKWebView renderuje przezroczyste tła inaczej niż UIWebview. Więcej szczegółów znajdziesz w opisie commita.

Nieobsługiwane:

scalesPageToFit (commit)

WKWebView nie obsługiwał właściwości scalesPageToFit, więc nie mogliśmy zaimplementować tego w komponencie WebView React Native.

Aktualizacje API Dostępności

· 6 minut czytania
Ziqi Chen
Student na UC Berkeley
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 →

Motywacja

Wraz z postępem technologicznym i rosnącym znaczeniem aplikacji mobilnych w codziennym życiu, rośnie także potrzeba tworzenia dostępnych aplikacji.

Ograniczone API Dostępności React Native zawsze było dużym problemem dla developerów, dlatego wprowadziliśmy kilka aktualizacji, aby ułatwić tworzenie inkluzywnych aplikacji mobilnych.

Problemy z istniejącym API

Problem pierwszy: Dwie zupełnie różne, a jednak podobne właściwości - accessibilityComponentType (Android) i accessibilityTraits (iOS)

accessibilityComponentType i accessibilityTraits to dwie właściwości służące do informowania TalkBack na Androidzie i VoiceOver na iOS, z jakim elementem interfejsu użytkownik ma do czynienia. Największe problemy z tymi właściwościami to:

  1. To dwie różne właściwości o różnych metodach użycia, ale tym samym celu. W poprzednim API były to osobne właściwości (po jednej na platformę), co było nie tylko niewygodne, ale też mylące dla wielu developerów. accessibilityTraits na iOS pozwala na 17 różnych wartości, podczas gdy accessibilityComponentType na Androidzie tylko na 4. Co więcej, wartości w większości się nie pokrywały. Nawet typy danych wejściowych różnią się: accessibilityTraits akceptuje tablicę cech lub pojedynczą cechę, podczas gdy accessibilityComponentType tylko pojedynczą wartość.

  2. Bardzo ograniczona funkcjonalność na Androidzie. Przy starej właściwości TalkBack rozpoznawał tylko elementy: "button", "radiobutton_checked" i "radiobutton_unchecked".

Problem drugi: Brak podpowiedzi dostępności

Podpowiedzi dostępności pomagają użytkownikom TalkBack i VoiceOver zrozumieć, co się stanie po wykonaniu akcji na elemencie dostępności, gdy nie jest to oczywiste na podstawie samej etykiety. Te podpowiedzi można włączać i wyłączać w panelu ustawień. Poprzednio API React Native w ogóle nie obsługiwało podpowiedzi dostępności.

Problem trzeci: Ignorowanie odwróconych kolorów

Niektórzy użytkownicy z wadami wzroku używają odwróconych kolorów w telefonach, aby uzyskać większy kontrast ekranu. Apple udostępniło API dla iOS, które pozwala developerom ignorować określone widoki. Dzięki temu obrazy i filmy nie są zniekształcane, gdy użytkownik ma włączone odwrócone kolory. To API nie jest obecnie obsługiwane przez React Native.

Projekt nowego API

Rozwiązanie pierwsze: Połączenie accessibilityComponentType (Android) i accessibilityTraits (iOS)

Aby rozwiązać problem rozbieżności między accessibilityComponentType a accessibilityTraits, postanowiliśmy połączyć je w jedną właściwość. To rozwiązanie miało sens, ponieważ technicznie pełnią tę samą funkcję, a ich połączenie zwalnia developerów z konieczności martwienia się o specyfikę platformy przy budowaniu funkcji dostępności.

Tło

W iOS UIAccessibilityTraits to właściwość, którą można ustawić na dowolnym obiekcie NSObject. Każda z 17 cech przekazanych przez właściwość JavaScript do natywnych jest mapowana na element UIAccessibilityTraits w Objective-C. Cechy są reprezentowane przez wartości typu long int, a każda ustawiona cecha jest łączona operatorem OR.

W Androidzie jednak AccessibilityComponentType to koncept wymyślony przez React Native, który nie ma bezpośredniego odpowiednika we właściwościach Androida. Dostępność jest obsługiwana przez delegata dostępności. Każdy widok ma domyślnego delegata. Aby dostosować dowolne akcje dostępności, należy utworzyć nowego delegata, nadpisać konkretne metody, które chcemy dostosować, a następnie ustawić delegata dostępności dla obsługiwanego widoku. Gdy developer ustawiał AccessibilityComponentType, natywny kod tworzył nowego delegata na podstawie przekazanego komponentu i przypisywał go do widoku.

Wprowadzone zmiany

Dla naszej nowej właściwości chcieliśmy stworzyć superset obu istniejących właściwości. Zdecydowaliśmy się wzorować nową właściwość głównie na istniejącej accessibilityTraits, ponieważ accessibilityTraits ma znacznie więcej wartości. Funkcjonalność dla Androida zostanie zapewniona poprzez modyfikację Delegata Dostępności.

Istnieje 17 wartości UIAccessibilityTraits, które można ustawić dla accessibilityTraits w iOS. Jednak nie uwzględniliśmy wszystkich jako możliwych wartości dla nowej właściwości. Dzieje się tak, ponieważ efekt ustawienia niektórych z tych cech jest mało znany, a wiele wartości praktycznie nigdy nie jest używanych.

Wartości UIAccessibilityTraits generalnie pełniły jedną z dwóch funkcji: opisywały rolę elementu interfejsu lub jego stan. W większości obserwowanych przypadków używano jednej wartości reprezentującej rolę w połączeniu z "state selected", "state disabled" lub obydwoma. Dlatego zdecydowaliśmy się stworzyć dwie nowe właściwości dostępności: accessibilityRole i accessibilityState.

accessibilityRole

Nowa właściwość accessibilityRole służy do informowania TalkBacka lub Voiceovera o roli elementu interfejsu. Może przyjmować jedną z następujących wartości:

  • none

  • button

  • link

  • search

  • image

  • keyboardkey

  • text

  • adjustable

  • header

  • summary

  • imagebutton

Ta właściwość pozwala na przekazanie tylko jednej wartości, ponieważ elementy interfejsu generalnie nie pełnią logicznie więcej niż jednej z tych ról. Wyjątkiem jest połączenie obrazu i przycisku, dlatego dodaliśmy rolę imagebutton będącą kombinacją obu.

accessibilityStates

Nowa właściwość accessibilityStates służy do informowania TalkBacka lub Voiceovera o stanie elementu interfejsu. Przyjmuje tablicę zawierającą jedną lub obie z następujących wartości:

  • selected

  • disabled

Rozwiązanie drugie: Dodawanie podpowiedzi dostępności

W tym celu dodaliśmy nową właściwość accessibilityHint. Jej ustawienie umożliwi TalkBackowi lub Voiceoverowi odczytanie podpowiedzi użytkownikom.

accessibilityHint

Ta właściwość przyjmuje podpowiedź dostępności w formie ciągu znaków (String) do odczytania.

W iOS ustawienie tej właściwości konfiguruje natywną właściwość AccessibilityHint widoku. Podpowiedź będzie odczytywana przez Voiceover, jeśli podpowiedzi dostępności są włączone w ustawieniach iPhone'a.

W Androidzie ustawienie tej właściwości dołącza wartość podpowiedzi na końcu etykiety dostępności. Zaleta tego rozwiązania polega na naśladowaniu zachowania podpowiedzi w iOS, ale wadą jest to, że w Androidzie nie można wyłączyć tych podpowiedzi w ustawieniach tak jak w iOS.

Podjęliśmy tę decyzję dla Androida, ponieważ podpowiedzi dostępności zwykle odpowiadają konkretnej akcji (np. kliknięciu) i chcieliśmy zachować spójne zachowanie między platformami.

Rozwiązanie problemu trzeciego

accessibilityIgnoresInvertColors

Udostępniliśmy w JavaScript interfejs API Apple AccessibilityIgnoresInvertColors. Teraz gdy masz widok, którego kolory nie powinny być inwertowane (np. obraz), możesz ustawić tę właściwość na true, a kolory nie zostaną odwrócone.

Nowe zastosowanie

Te nowe właściwości będą dostępne w wydaniu React Native 0.57.

Jak przeprowadzić aktualizację

Jeśli obecnie używasz accessibilityComponentType i accessibilityTraits, oto kroki, które możesz podjąć, aby przejść na nowe właściwości.

1. Używanie jscodeshift

Najprostsze przypadki użycia można zastąpić, uruchamiając skrypt jscodeshift.

Ten skrypt zastępuje następujące przypadki:

accessibilityTraits=“trait”
accessibilityTraits={[“trait”]}

Zastąpiono przez

accessibilityRole= “trait”

Ten skrypt usuwa również wystąpienia AccessibilityComponentType (zakładając, że wszędzie tam, gdzie ustawiono AccessibilityComponentType, ustawiono również AccessibilityTraits).

2. Używanie ręcznego codemodu

W przypadkach, w których używano AccessibilityTraits bez odpowiedniej wartości dla AccessibilityRole, oraz w przypadkach, gdy do AccessibilityTraits przekazywano wiele cech, konieczne było wykonanie ręcznego codemodu.

Ogólnie rzecz biorąc,

accessibilityTraits= {[“button”, “selected”]}

byłyby ręcznie zastąpione przez

accessibilityRole=“button”
accessibilityStates={[“selected”]}

Te właściwości są już używane w bazie kodu Facebooka. Codemod dla Facebooka był zaskakująco prosty. Skrypt jscodeshift naprawił około połowy naszych przypadków, a druga połowa została naprawiona ręcznie. Cały proces trwał mniej niż kilka godzin.

Mamy nadzieję, że zaktualizowane API okaże się przydatne! I prosimy, kontynuujcie tworzenie dostępnych aplikacji! #inclusion

Stan React Native w 2018 roku

· 5 minut czytania
Sophie Alpert
Kierownik ds. Inżynierii Reacta 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ęło trochę czasu od naszego ostatniego raportu o stanie React Native.

W Facebooku używamy React Native bardziej niż kiedykolwiek w wielu ważnych projektach. Jednym z naszych najpopularniejszych produktów jest Marketplace – jedna z głównych zakładek w naszej aplikacji, z której korzysta 800 milionów osób miesięcznie. Od momentu powstania w 2015 roku cały Marketplace został zbudowany w React Native, obejmując ponad sto pełnoekranowych widoków w różnych częściach aplikacji.

React Native wykorzystujemy także w wielu nowych sekcjach aplikacji. Jeśli oglądaliście zeszłomiesięczny keynote F8, rozpoznacie funkcje takie jak Krwiodawstwo, Reagowanie na kryzysy, Skróty prywatności i Kontrole zdrowia – wszystkie niedawno wprowadzone i zbudowane w React Native. Projekty poza główną aplikacją Facebooka również korzystają z React Native. Nowe gogle VR Oculus Go zawierają aplikację mobilną towarzyszącą w całości zbudowaną w React Native, nie wspominając już o React VR napędzającym wiele funkcji w samych goglach.

Naturalnie korzystamy też z wielu innych technologii do budowania naszych aplikacji. Litho i ComponentKit to dwie biblioteki, których szeroko używamy; obie zapewniają API komponentów podobne do Reacta do budowania natywnych ekranów. React Native nigdy nie miał zastąpić wszystkich innych technologii – skupiamy się na ulepszaniu samego React Native, ale cieszymy się, gdy inne zespoły zapożyczają nasze pomysły, jak wprowadzenie natychmiastowego przeładowania do kodu niebędącego JavaScriptem.

Architektura

Gdy w 2013 roku rozpoczynaliśmy projekt React Native, zaprojektowaliśmy go z pojedynczym "mostem" między JavaScriptem a kodem natywnym, który jest asynchroniczny, możliwy do serializacji i przetwarzany wsadowo. Tak jak React DOM przekształca aktualizacje stanu w imperatywne wywołania API DOM typu document.createElement(attrs) i .appendChild(), tak React Native został zaprojektowany do zwracania pojedynczej wiadomości JSON listującej mutacje do wykonania, jak [["createView", attrs], ["manageChildren", ...]]. Zaprojektowaliśmy cały system tak, by nigdy nie polegał na synchronicznej odpowiedzi i by zapewnić pełną serializowalność całej listy do JSONa i z powrotem. Zrobiliśmy to dla elastyczności: na tej architekturze zbudowaliśmy narzędzia takie jak debugowanie w Chrome, które asynchronicznie wykonuje cały kod JavaScript przez połączenie WebSocket.

Przez ostatnie 5 lat odkryliśmy, że te początkowe założenia utrudniają implementację niektórych funkcji. Asynchroniczny most uniemożliwia bezpośrednią integrację logiki JavaScript z wieloma natywnymi API oczekującymi synchronicznych odpowiedzi. Wsadowe przetwarzanie wywołań natywnych utrudnia wywoływanie z aplikacji React Native funkcji zaimplementowanych natywnie. A serializowalny most oznacza niepotrzebne kopiowanie zamiast bezpośredniego współdzielenia pamięci między obu światami. Dla aplikacji całkowicie zbudowanych w React Native te ograniczenia są zwykle akceptowalne. Ale dla aplikacji z złożoną integracją między React Native a istniejącym kodem są frustrujące.

Pracujemy nad dużą przebudową architektury React Native, aby framework był bardziej elastyczny i lepiej integrował się z natywną infrastrukturą w hybrydowych aplikacjach JavaScript/natywnych. W tym projekcie zastosujemy wiedzę zdobytą przez ostatnie 5 lat i stopniowo przejdziemy do nowocześniejszej architektury. Przepisujemy wiele wewnętrznych elementów React Native, ale większość zmian odbywa się pod maską: istniejące aplikacje React Native będą działać z niewielkimi modyfikacjami lub bez nich.

Aby React Native był lżejszy i lepiej integrował się z istniejącymi natywnymi aplikacjami, ta rearchitektura wprowadza trzy główne wewnętrzne zmiany. Po pierwsze, zmieniamy model wątkowości. Zamiast wymagać od każdej aktualizacji UI pracy na trzech różnych wątkach, będzie możliwe synchroniczne wywoływanie JavaScriptu z dowolnego wątku dla wysokopriorytetowych aktualizacji, przy jednoczesnym utrzymaniu niskopriorytetowych zadań poza wątkiem głównym dla zachowania responsywności. Po drugie, włączamy możliwości async rendering do React Native, co umożliwi wielopoziomowe priorytety renderowania i uprości obsługę asynchronicznych danych. Wreszcie, upraszczamy nasz mostek, aby był szybszy i lżejszy; bezpośrednie wywołania między natywnym kodem a JavaScriptem są bardziej wydajne i ułatwią budowę narzędzi debugujących takich jak ślady stosu międzyjęzykowego.

Po wprowadzeniu tych zmian możliwe będą ściślejsze integracje. Obecnie włączenie natywnej nawigacji, obsługi gestów czy komponentów takich jak UICollectionView i RecyclerView bez skomplikowanych obejść jest niemożliwe. Po zmianach w modelu wątkowości tworzenie takich funkcji stanie się proste.

Udostępnimy więcej szczegółów na temat tej pracy później w tym roku, gdy będzie bliżej ukończenia.

Społeczność

Oprócz wewnętrznej społeczności w Facebooku, cieszymy się, że na zewnątrz istnieje prężna społeczność użytkowników i współtwórców React Native. Chcemy lepiej wspierać społeczność React Native, zarówno lepiej służąc użytkownikom, jak i ułatwiając współtworzenie projektu.

Tak jak nasze zmiany architektoniczne pomogą React Native czyściej współdziałać z inną natywną infrastrukturą, React Native powinien być szczuplejszy po stronie JavaScriptu, aby lepiej pasować do ekosystemu JavaScript – w tym umożliwiając wymianę maszyny wirtualnej i bundlera. Wiemy, że tempo zmian łamiących kompatybilność może być trudne do nadążenia, więc chcemy znaleźć sposoby na rzadsze wydawanie wersji głównych. Wreszcie, wiemy że niektóre zespoły poszukują bardziej dogłębnej dokumentacji w tematach takich jak optymalizacja uruchamiania, gdzie nasza ekspertyza nie została jeszcze spisana. Spodziewajcie się takich zmian w nadchodzącym roku.

Jeśli używasz React Native, jesteś częścią naszej społeczności – dziel się z nami swoimi przemyśleniami, jak możemy ulepszyć React Native dla Ciebie.

React Native to tylko jedno z narzędzi w zestawie developera mobilnego, ale wierzymy w nie mocno – i ulepszamy je każdego dnia, z ponad 2500 commitami w ostatnim roku od 500+ współtwórców.

Korzystanie z TypeScript w React Native

· 7 minut czytania
Ash Furrow
Inżynier Oprogramowania w Artsy
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 →

JavaScript! Wszyscy go kochamy. Ale niektórzy z nas uwielbiają także typy. Na szczęście istnieją rozwiązania pozwalające dodać silniejsze typowanie do JavaScript. Moim ulubionym jest TypeScript, ale React Native natywnie wspiera Flow. Wybór między nimi zależy od preferencji – każde podejście inaczej dodaje magię typów do JavaScript. Dzisiaj przyjrzymy się, jak używać TypeScript w aplikacjach React Native.

Ten wpis korzysta z repozytorium Microsoftu TypeScript-React-Native-Starter jako przewodnika.

Aktualizacja: Od czasu powstania tego wpisu proces stał się jeszcze prostszy. Możesz zastąpić całą konfigurację opisaną w tym artykule, wykonując jedno polecenie:

npx react-native init MyAwesomeProject --template react-native-template-typescript

Istnieją jednak pewne ograniczenia w obsłudze TypeScript przez Babel, które szczegółowo omówiono w powyższym artykule. Kroki opisane w tym wpisie nadal działają, a Artsy nadal używa react-native-typescript-transformer w produkcji, ale najszybszym sposobem na rozpoczęcie pracy z React Native i TypeScript jest użycie powyższego polecenia. Zawsze możesz przełączyć się później, jeśli zajdzie taka potrzeba.

W każdym razie – dobrej zabawy! Oryginalny wpis blogowy kontynuujemy poniżej.

Wymagania wstępne

Ponieważ możesz rozwijać aplikacje na różnych platformach dla różnych typów urządzeń, podstawowa konfiguracja może być złożona. Najpierw upewnij się, że potrafisz uruchomić zwykłą aplikację React Native bez TypeScript. Postępuj zgodnie z instrukcjami na stronie React Native, aby rozpocząć. Gdy uda ci się wdrożyć aplikację na urządzeniu lub emulatorze, będziesz gotowy do stworzenia aplikacji React Native z TypeScript.

Będziesz także potrzebować Node.js, npm i Yarn.

Inicjalizacja

Gdy już spróbujesz stworzyć szkielet zwykłego projektu React Native, będziesz gotowy, aby dodać TypeScript. Zróbmy to teraz.

react-native init MyAwesomeProject
cd MyAwesomeProject

Dodawanie TypeScript

Następnym krokiem jest dodanie TypeScript do projektu. Poniższe polecenia:

  • dodadzą TypeScript do twojego projektu

  • dodadzą React Native TypeScript Transformer do projektu

  • zainicjują pusty plik konfiguracyjny TypeScript, który skonfigurujemy później

  • dodadzą pusty plik konfiguracyjny React Native TypeScript Transformer, który skonfigurujemy później

  • dodadzą definicje typów dla React i React Native

OK, uruchommy te polecenia.

yarn add --dev typescript
yarn add --dev react-native-typescript-transformer
yarn tsc --init --pretty --jsx react
touch rn-cli.config.js
yarn add --dev @types/react @types/react-native

Plik tsconfig.json zawiera wszystkie ustawienia kompilatora TypeScript. Domyślne wartości utworzone przez powyższe polecenie są w większości poprawne, ale otwórz plik i odkomentuj następującą linię:

{
/* Search the config file for the following line and uncomment it. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
}

Plik rn-cli.config.js zawiera ustawienia dla React Native TypeScript Transformer. Otwórz go i dodaj następujący kod:

module.exports = {
getTransformModulePath() {
return require.resolve('react-native-typescript-transformer');
},
getSourceExts() {
return ['ts', 'tsx'];
},
};

Migracja do TypeScript

Zmień nazwy wygenerowanych plików App.js i __tests_/App.js na App.tsx. Plik index.js musi zachować rozszerzenie .js. Wszystkie nowe pliki powinny używać rozszerzenia .tsx (lub .ts, jeśli plik nie zawiera JSX).

Gdybyś spróbował teraz uruchomić aplikację, otrzymałbyś błąd podobny do object prototype may only be an object or null. Jest to spowodowane niepowodzeniem w zaimportowaniu domyślnego eksportu z React oraz nazwanego eksportu w tej samej linii. Otwórz plik App.tsx i zmodyfikuj import na początku pliku:

-import React, { Component } from 'react';
+import React from 'react'
+import { Component } from 'react';

Część tego problemu wynika z różnic w sposobie współdziałania Babela i TypeScripta z modułami CommonJS. W przyszłości oba narzędzia ustabilizują się pod kątem tego samego zachowania.

W tym momencie powinieneś być w stanie uruchomić aplikację React Native.

Dodawanie infrastruktury testowej TypeScript

React Native dostarczany jest z Jest, więc aby testować aplikację React Native z TypeScript, dodamy ts-jest do naszych devDependencies.

yarn add --dev ts-jest

Następnie otworzymy nasz package.json i zastąpimy pole jest następującą konfiguracją:

{
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"transform": {
"^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
"\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
"testPathIgnorePatterns": [
"\\.snap$",
"<rootDir>/node_modules/"
],
"cacheDirectory": ".jest/cache"
}
}

To skonfiguruje Jesta do uruchamiania plików .ts i .tsx za pomocą ts-jest.

Instalowanie deklaracji typów zależności

Aby uzyskać najlepsze doświadczenia w TypeScript, potrzebujemy, aby sprawdzanie typów rozumiało strukturę i API naszych zależności. Niektóre biblioteki publikują swoje pakiety z plikami .d.ts (deklaracje typów/definicje typów), które opisują strukturę podstawowego JavaScriptu. Dla innych bibliotek musimy jawnie zainstalować odpowiedni pakiet z zakresu npm @types/.

Na przykład będziemy potrzebować typów dla Jesta, Reacta, React Native oraz React Test Renderer.

yarn add --dev @types/jest @types/react @types/react-native @types/react-test-renderer

Zapisaliśmy te pakiety deklaracji jako zależności dev, ponieważ jest to aplikacja React Native używająca tych zależności wyłącznie podczas rozwoju, a nie w czasie działania. Gdybyśmy publikowali bibliotekę na NPM, musielibyśmy dodać niektóre z tych zależności typów jako zwykłe zależności.

Więcej o uzyskiwaniu plików .d.ts możesz przeczytać tutaj.

Ignorowanie dodatkowych plików

W systemie kontroli wersji warto zignorować folder .jest. Jeśli używasz gita, możesz dodać wpisy do pliku .gitignore.

# Jest
#
.jest/

Jako punkt kontrolny warto zatwierdzić pliki w systemie kontroli wersji.

git init
git add .gitignore # import to do this first, to ignore our files
git add .
git commit -am "Initial commit."

Dodawanie komponentu

Dodajmy komponent do naszej aplikacji. Stwórzmy komponent Hello.tsx. Jest to komponent dydaktyczny - nie coś, co napisałbyś w rzeczywistej aplikacji, ale przykład pokazujący nietrywialne użycie TypeScript w React Native.

Utwórz katalog components i dodaj następujący przykład:

// components/Hello.tsx
import React from 'react';
import {Button, StyleSheet, Text, View} from 'react-native';

export interface Props {
name: string;
enthusiasmLevel?: number;
}

interface State {
enthusiasmLevel: number;
}

export class Hello extends React.Component<Props, State> {
constructor(props: Props) {
super(props);

if ((props.enthusiasmLevel || 0) <= 0) {
throw new Error(
'You could be a little more enthusiastic. :D',
);
}

this.state = {
enthusiasmLevel: props.enthusiasmLevel || 1,
};
}

onIncrement = () =>
this.setState({
enthusiasmLevel: this.state.enthusiasmLevel + 1,
});
onDecrement = () =>
this.setState({
enthusiasmLevel: this.state.enthusiasmLevel - 1,
});
getExclamationMarks = (numChars: number) =>
Array(numChars + 1).join('!');

render() {
return (
<View style={styles.root}>
<Text style={styles.greeting}>
Hello{' '}
{this.props.name +
this.getExclamationMarks(this.state.enthusiasmLevel)}
</Text>

<View style={styles.buttons}>
<View style={styles.button}>
<Button
title="-"
onPress={this.onDecrement}
accessibilityLabel="decrement"
color="red"
/>
</View>

<View style={styles.button}>
<Button
title="+"
onPress={this.onIncrement}
accessibilityLabel="increment"
color="blue"
/>
</View>
</View>
</View>
);
}
}

// styles
const styles = StyleSheet.create({
root: {
alignItems: 'center',
alignSelf: 'center',
},
buttons: {
flexDirection: 'row',
minHeight: 70,
alignItems: 'stretch',
alignSelf: 'center',
borderWidth: 5,
},
button: {
flex: 1,
paddingVertical: 0,
},
greeting: {
color: '#999',
fontWeight: 'bold',
},
});

Wow! To sporo, ale przeanalizujmy to:

  • Zamiast renderować elementy HTML jak div, span, h1 itd., renderujemy komponenty takie jak View i Button. Są to natywne komponenty działające na różnych platformach.

  • Stylowanie określamy za pomocą funkcji StyleSheet.create dostarczonej przez React Native. Arkusze stylów React pozwalają kontrolować układ przy użyciu Flexboxa i stylizować przy użyciu konstrukcji podobnych do CSS.

Dodawanie testu komponentu

Skoro mamy już komponent, przetestujmy go.

Mamy już zainstalowanego Jesta jako runner testów. Będziemy pisać testy snapshotów dla naszych komponentów, więc dodajmy wymagane rozszerzenie do testów snapshotów:

yarn add --dev react-addons-test-utils

Teraz utwórz folder __tests__ w katalogu components i dodaj test dla Hello.tsx:

// components/__tests__/Hello.tsx
import React from 'react';
import renderer from 'react-test-renderer';

import {Hello} from '../Hello';

it('renders correctly with defaults', () => {
const button = renderer
.create(<Hello name="World" enthusiasmLevel={1} />)
.toJSON();
expect(button).toMatchSnapshot();
});

Podczas pierwszego uruchomienia testu zostanie utworzony migawkowy zapis wyrenderowanego komponentu, który zostanie zapisany w pliku components/__tests__/__snapshots__/Hello.tsx.snap. Po wprowadzeniu zmian w komponencie konieczne będzie zaktualizowanie migawek i przejrzenie ich pod kątem nieoczekiwanych zmian. Więcej o testowaniu komponentów React Native można przeczytać tutaj.

Kolejne kroki

Zapoznaj się z oficjalnym samouczkiem React oraz biblioteką do zarządzania stanem Redux. Te zasoby mogą okazać się pomocne podczas tworzenia aplikacji React Native. Dodatkowo warto przyjrzeć się bibliotece komponentów ReactXP, napisanej w całości w TypeScript i obsługującej zarówno React na webie, jak i React Native.

Powodzenia w bardziej bezpiecznym typowo środowisku programistycznym React Native!

Tworzenie komponentu <InputAccessoryView> dla React Native

· 5 minut czytania
Peter Argany
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 →

Motywacja

Trzy lata temu zgłoszono problem na GitHubie dotyczący dodania obsługi widżetu pomocniczego klawiatury w React Native.

Przez kolejne lata pojawiały się liczne "+1", różne obejścia i zero konkretnych zmian w RN w tej sprawie - aż do dziś. Zaczynając od iOS, udostępniamy API do obsługi natywnego widżetu pomocniczego klawiatury i z przyjemnością dzielimy się szczegółami implementacji.

Kontekst

Czym dokładnie jest widżet pomocniczy klawiatury? Z dokumentacji Apple dowiadujemy się, że to niestandardowy widok kotwiczony u góry systemowej klawiatury, gdy obiekt staje się first responder. Każdy obiekt dziedziczący po UIResponder może przedefiniować właściwość .inputAccessoryView jako read-write i zarządzać niestandardowym widokiem. Infrastruktura responderów montuje widok i synchronizuje go z klawiaturą systemową. Gesty zamykające klawiaturę (przeciągnięcie lub dotknięcie) są automatycznie stosowane do widżetu pomocniczego. Pozwala to budować interfejsy z interaktywnym zamykaniem klawiatury - kluczową funkcją w aplikacjach takich jak iMessage czy WhatsApp.

Istnieją dwa główne zastosowania dla kotwiczenia widoku nad klawiaturą. Pierwsze to tworzenie paska narzędzi klawiatury, jak selektor tła w kreatorze Facebooka.

W tym scenariuszu klawiatura jest skupiona na polu tekstowym, a widżet pomocniczy dostarcza dodatkowej funkcjonalności kontekstowej. W aplikacji mapowej mogą to być sugestie adresów, a w edytorze tekstu - narzędzia formatowania.


Obiektem Objective-C UIResponder posiadającym <InputAccessoryView> w tym przypadku jest wyraźnie <TextInput> stający się first responderem, który pod maską staje się instancją UITextView lub UITextField.

Drugi typowy scenariusz to przyklejone pola tekstowe:

Tutaj pole tekstowe jest częścią samego widżetu pomocniczego. Rozwiązanie powszechnie stosowane w aplikacjach messengeringowych, gdzie wiadomość można komponować podczas przewijania historii.


Kto posiada <InputAccessoryView> w tym przykładzie? Czy może to być znowu UITextView/UITextField? Pole tekstowe jest WEWNĄTRZ widżetu pomocniczego - tworzy to zależność cykliczną. Rozwiązanie tego problemu to temat na osobny artykuł. Spoiler: właścicielem jest generyczna podklasa UIView, której ręcznie każemy zostać first responderem.

Projekt API

Znając już zastosowania <InputAccessoryView>, kolejnym krokiem było zaprojektowanie API uwzględniającego oba scenariusze i współpracującego z istniejącymi komponentami RN jak <TextInput>.

Dla pasków narzędzi klawiatury istotne były:

  1. Możliwość umieszczenia dowolnej hierarchii widoków RN w <InputAccessoryView>

  2. Zdolność tej odłączonej hierarchii do odbierania dotknięć i modyfikowania stanu aplikacji

  3. Powiązanie <InputAccessoryView> z konkretnym <TextInput>

  4. Możliwość współdzielenia jednego <InputAccessoryView> między wieloma polami tekstowymi

Punkt 1 osiągnęliśmy za pomocą koncepcji zbliżonej do portali React. W tym podejściu "przenosimy" widoki RN do hierarchii UIView zarządzanej przez infrastrukturę responderów. Ponieważ widoki RN renderują się jako UIView, jest to proste - wystarczy nadpisać:

- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex

i przekierować wszystkie subview do nowej hierarchii UIView. Dla punktu 2 skonfigurowaliśmy nowy RCTTouchHandler dla <InputAccessoryView>. Aktualizacje stanu realizowane są standardowymi callbackami. Dla punktów 3-4 użyliśmy pola nativeID do lokalizacji widżetu w kodzie natywnym podczas tworzenia komponentu <TextInput>. Funkcja ta wykorzystuje właściwość .inputAccessoryView natywnego pola tekstowego, skutecznie łącząc <InputAccessoryView> z <TextInput> w ich implementacjach ObjC.

Obsługa przyklejonych pól tekstowych (scenariusz 2) dodaje dodatkowe ograniczenia. Ponieważ pole tekstowe jest dzieckiem widżetu pomocniczego, powiązanie przez nativeID nie wchodzi w grę. Zamiast tego ustawiamy .inputAccessoryView generycznej UIView (poza ekranem) na naszą natywną hierarchię <InputAccessoryView>. Ręczne uczynienie tej UIView first responderem powoduje zamontowanie widżetu przez infrastrukturę responderów - koncepcja dokładnie wyjaśniona we wspomnianym artykule.

Wyzwania

Proces tworzenia tego API nie był pozbawiony wyzwań. Oto napotkane problemy i ich rozwiązania.

Początkowy pomysł zakładał nasłuchiwanie zdarzeń UIKeyboardWill(Show/Hide/ChangeFrame) w NSNotificationCenter. Ten wzorzec stosowany jest w bibliotekach open-source'owych i wewnętrznie w aplikacji Facebooka. Niestety, zdarzenia UIKeyboardDidChangeFrame nie były wywoływane na czas, aby zaktualizować ramkę <InputAccessoryView> podczas przeciągania, a zmiany wysokości klawiatury nie były wychwytywane. Powodowało to błędy typu:

Na iPhone X klawiatura tekstowa i emoji mają różne wysokości. Większość aplikacji używających zdarzeń klawiatury musiała łatać ten błąd. Naszym rozwiązaniem było pełne wykorzystanie .inputAccessoryView, gdzie infrastruktura responderów automatycznie obsługuje takie aktualizacje.


Kolejny podchwytliwy błąd dotyczył omijania przycisku Home na iPhone X. Można pomyśleć: "Apple stworzył safeAreaLayoutGuide właśnie po to!". Byliśmy równie naiwni. Problem? Natywna implementacja <InputAccessoryView> nie ma okna do zakotwiczenia aż do momentu pojawienia się. Rozwiązaliśmy to nadpisując -(BOOL)becomeFirstResponder i wymuszając constraintsy w tym momencie. Ale pojawił się kolejny problem:

Widżet omija przycisk Home, ale treść z obszaru unsafe staje się widoczna. Rozwiązanie znaleźliśmy w tym radarze. Owinęliśmy natywną hierarchię <InputAccessoryView> kontenerem ignorującym safeAreaLayoutGuide. Kontener zakrywa treść w unsafe area, podczas gdy <InputAccessoryView> pozostaje w bezpiecznej strefie.


Przykład użycia

Oto przykład przycisku resetującego stan <TextInput> na pasku narzędzi:

class TextInputAccessoryViewExample extends React.Component<
{},
*,
> {
constructor(props) {
super(props);
this.state = {text: 'Placeholder Text'};
}

render() {
const inputAccessoryViewID = 'inputAccessoryView1';
return (
<View>
<TextInput
style={styles.default}
inputAccessoryViewID={inputAccessoryViewID}
onChangeText={text => this.setState({text})}
value={this.state.text}
/>
<InputAccessoryView nativeID={inputAccessoryViewID}>
<View style={{backgroundColor: 'white'}}>
<Button
onPress={() =>
this.setState({text: 'Placeholder Text'})
}
title="Reset Text"
/>
</View>
</InputAccessoryView>
</View>
);
}
}

Przykład przyklejonych pól tekstowych znajdziesz w repozytorium.

Kiedy będzie dostępne?

Pełna implementacja tej funkcjonalności jest dostępna w tym commicie. Komponent <InputAccessoryView> będzie dostępny w nadchodzącym wydaniu wersji v0.55.0.

Miłego pisania :)

Korzystanie z AWS w React Native

· 10 minut czytania
Richard Threlkeld
Starszy Kierownik Produktu Technicznego w AWS Mobile
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 →

AWS jest powszechnie znanym w branży technologicznej dostawcą usług chmurowych. Obejmują one technologie obliczeniowe, magazynowe i bazodanowe, a także w pełni zarządzane rozwiązania serwerless. Zespół AWS Mobile ściśle współpracuje z klientami i członkami ekosystemu JavaScript, aby aplikacje mobilne i webowe połączone z chmurą były bezpieczniejsze, skalowalne oraz łatwiejsze w tworzeniu i wdrażaniu. Rozpoczęliśmy od kompletu startowego, ale mamy też nowsze rozwiązania.

W tym wpisie omówimy kilka ciekawych rozwiązań dla developerów React i React Native:

  • AWS Amplify, deklaratywna biblioteka dla aplikacji JavaScript korzystających z usług chmurowych

  • AWS AppSync, w pełni zarządzana usługa GraphQL z funkcjami offline i czasu rzeczywistego

AWS Amplify

Aplikacje React Native są bardzo łatwe do uruchomienia przy użyciu narzędzi takich jak Create React Native App czy Expo. Jednak połączenie ich z chmurą może stanowić wyzwanie, gdy próbujesz dopasować przypadki użycia do usług infrastrukturalnych. Na przykład Twoja aplikacja React Native może wymagać przesyłania zdjęć. Czy powinny być one chronione per użytkownik? To prawdopodobnie oznacza potrzebę rejestracji lub logowania. Chcesz mieć własny katalog użytkowników czy korzystasz z dostawcy mediów społecznościowych? Być może aplikacja potrzebuje też wywoływać API z własną logiką biznesową po zalogowaniu użytkowników.

Aby pomóc developerom JavaScript w tych problemach, wydaliśmy bibliotekę o nazwie AWS Amplify. Jej projekt podzielono na "kategorie" zadań, zamiast implementacji specyficznych dla AWS. Na przykład, jeśli chcesz, aby użytkownicy rejestrowali się, logowali, a następnie przesyłali prywatne zdjęcia, wystarczy dodać do aplikacji kategorie Auth i Storage:

import { Auth } from 'aws-amplify';

Auth.signIn(username, password)
.then(user => console.log(user))
.catch(err => console.log(err));

Auth.confirmSignIn(user, code)
.then(data => console.log(data))
.catch(err => console.log(err));

W powyższym kodzie widać przykłady typowych zadań, w których Amplify może pomóc, jak używanie kodów uwierzytelniania wieloskładnikowego (MFA) przez e-mail lub SMS. Obecnie obsługiwane kategorie to:

  • Auth: Zapewnia automatyzację poświadczeń. Gotowa implementacja wykorzystuje dane uwierzytelniające AWS do podpisywania oraz tokeny JWT OIDC z Amazon Cognito. Obsługiwane są typowe funkcje, takie jak MFA.

  • Analytics: Jedną linijką kodu uzyskaj śledzenie uwierzytelnionych i nieuwierzytelnionych użytkowników w Amazon Pinpoint. Możesz rozszerzyć to o własne metryki lub atrybuty.

  • API: Zapewnia bezpieczną interakcję z interfejsami RESTful API, wykorzystując AWS Signature Version 4. Moduł API doskonale sprawdza się w infrastrukturach serwerless z Amazon API Gateway.

  • Storage: Uproszczone polecenia do przesyłania, pobierania i listowania treści w Amazon S3. Możesz też łatwo grupować dane jako publiczne lub prywatne per użytkownik.

  • Caching: Interfejs pamięci podręcznej LRU działający zarówno w aplikacjach webowych, jak i React Native, wykorzystujący specyficzną dla implementacji trwałość.

  • i18n and Logging: Zapewnia możliwości internacjonalizacji i lokalizacji oraz debugowania i logowania.

Jedną z zalet Amplify jest wbudowanie "najlepszych praktyk" w projekt dostosowany do Twojego środowiska programistycznego. Przykładowo, zauważyliśmy współpracując z klientami i developerami React Native, że skróty stosowane podczas rozwoju aplikacji dla szybkiego efektu często trafiały do środowisk produkcyjnych. To może naruszać skalowalność lub bezpieczeństwo, wymuszając przebudowę infrastruktury i refaktoryzację kodu.

Jednym z przykładów, jak pomagamy programistom uniknąć tego problemu, są Referencyjne architektury bezserwerowe z AWS Lambda. Pokazują one najlepsze praktyki współpracy Amazon API Gateway i AWS Lambda przy budowaniu zaplecza. Ten wzorzec został wbudowany w kategorię API Amplify. Możesz użyć tego wzorca do interakcji z wieloma różnymi punktami końcowymi REST i przekazywania nagłówków bezpośrednio do funkcji Lambda dla niestandardowej logiki biznesowej. Udostępniliśmy również AWS Mobile CLI do inicjowania nowych lub istniejących projektów React Native z tymi funkcjami. Aby rozpocząć, zainstaluj poprzez npm i postępuj zgodnie z monitami konfiguracyjnymi:

npm install --global awsmobile-cli
awsmobile configure

Kolejnym przykładem wbudowanych najlepszych praktyk specyficznych dla ekosystemu mobilnego jest bezpieczeństwo haseł. Domyślna implementacja kategorii Auth wykorzystuje pule użytkowników Amazon Cognito do rejestracji i logowania. Ta usługa implementuje protokół Secure Remote Password jako sposób ochrony użytkowników podczas prób uwierzytelniania. Jeśli chcesz zgłębić matematyczne podstawy protokołu, zauważysz, że musisz użyć dużej liczby pierwszej przy obliczaniu weryfikatora hasła nad pierwiastkiem pierwotnym do generowania grupy. W środowiskach React Native JIT jest wyłączony. To sprawia, że obliczenia BigInteger dla operacji bezpieczeństwa takich jak ta są mniej wydajne. Aby to zrekompensować, udostępniliśmy natywne mosty w Androidzie i iOS, które możesz podlinkować w swoim projekcie:

npm install --save aws-amplify-react-native
react-native link amazon-cognito-identity-js

Cieszymy się również, widząc że zespół Expo uwzględnił to w swoim najnowszym SDK, dzięki czemu możesz używać Amplify bez konieczności ejectowania.

Wreszcie, specjalnie dla rozwoju React Native (i React), Amplify zawiera komponenty wyższego rzędu (HOCs) do łatwego opakowywania funkcjonalności, takich jak rejestracja i logowanie w twojej aplikacji:

import Amplify, { withAuthenticator } from 'aws-amplify-react-native';
import aws_exports from './aws-exports';

Amplify.configure(aws_exports);

class App extends React.Component {
...
}

export default withAuthenticator(App);

Podstawowy komponent jest również dostarczany jako <Authenticator />, co daje pełną kontrolę nad dostosowywaniem interfejsu użytkownika. Dostarcza także właściwości do zarządzania stanem użytkownika, np. czy zalogował się czy czeka na potwierdzenie MFA, oraz callbacki, które możesz wywołać przy zmianie stanu.

Podobnie znajdziesz ogólne komponenty React do różnych przypadków użycia. Możesz je dostosować do swoich potrzeb, np. aby pokazać wszystkie prywatne obrazy z Amazon S3 w module Storage:

<S3Album
level="private"
path={path}
filter={(item) => /jpg/i.test(item.path)}/>

Możesz kontrolować wiele funkcji komponentów poprzez props, jak pokazano wcześniej, z opcjami publicznego lub prywatnego przechowywania. Istnieją nawet możliwości automatycznego zbierania analiz, gdy użytkownicy wchodzą w interakcję z określonymi komponentami UI:

return <S3Album track/>

AWS Amplify preferuje konwencję nad konfiguracją w stylu rozwoju, z globalną procedurą inicjalizacji lub inicjalizacją na poziomie kategorii. Najszybszym sposobem na rozpoczęcie jest użycie pliku aws-exports. Jednak programiści mogą również używać biblioteki niezależnie z istniejącymi zasobami.

Aby zgłębić filozofię i zobaczyć pełne demo, obejrzyj film z AWS re:Invent.

AWS AppSync

Krótko po premierze AWS Amplify, udostępniliśmy również AWS AppSync. To w pełni zarządzana usługa GraphQL z funkcjami offline i działania w czasie rzeczywistym. Chociaż możesz używać GraphQL w różnych językach programowania klienckiego (w tym natywnych Android i iOS), jest ona szczególnie popularna wśród programistów React Native. Dzieje się tak, ponieważ model danych doskonale wpasowuje się w jednokierunkowy przepływ danych i hierarchię komponentów.

AWS AppSync umożliwia łączenie się z zasobami w twoim własnym koncie AWS, co oznacza, że posiadasz i kontrolujesz swoje dane. Odbywa się to poprzez użycie źródeł danych, a usługa obsługuje Amazon DynamoDB, Amazon Elasticsearch oraz AWS Lambda. Dzięki temu możesz łączyć funkcjonalności (takie jak NoSQL i wyszukiwanie pełnotekstowe) w pojedynczym interfejsie API GraphQL jako schemat. Pozwala to na mieszanie i dopasowywanie źródeł danych. Usługa AppSync może również tworzyć zasoby na podstawie schematu, więc jeśli nie znasz usług AWS, możesz napisać schemat GraphQL w SDL, kliknąć przycisk i automatycznie rozpocząć pracę.

Funkcjonalność czasu rzeczywistego w AWS AppSync jest kontrolowana poprzez subskrypcje GraphQL z dobrze znanym wzorcem opartym na zdarzeniach. Ponieważ subskrypcje w AWS AppSync są kontrolowane na poziomie schematu za pomocą dyrektywy GraphQL, a schemat może używać dowolnego źródła danych, oznacza to, że możesz wyzwalać powiadomienia z operacji bazodanowych przy użyciu Amazon DynamoDB i Amazon Elasticsearch Service, lub z innych części twojej infrastruktury za pomocą AWS Lambda.

Podobnie jak w AWS Amplify, możesz używać funkcji bezpieczeństwa klasy enterprise w swoim interfejsie API GraphQL z AWS AppSync. Usługa pozwala szybko rozpocząć pracę z kluczami API. Jednak gdy przechodzisz do produkcji, możesz przejść na użycie AWS Identity and Access Management (IAM) lub tokenów OIDC z pul użytkowników Amazon Cognito. Możesz kontrolować dostęp na poziomie resolvera za pomocą polityk na typach. Możesz nawet używać sprawdzeń logicznych dla szczegółowej kontroli dostępu w czasie wykonywania, takich jak wykrywanie, czy użytkownik jest właścicielem określonego zasobu bazy danych. Istnieją również możliwości sprawdzania przynależności do grup w celu wykonywania resolverów lub dostępu do poszczególnych rekordów bazy danych.

Aby pomóc programistom React Native w poznaniu tych technologii, dostępny jest wbudowany przykładowy schemat GraphQL, który możesz uruchomić na stronie głównej konsoli AWS AppSync. Ten przykład wdraża schemat GraphQL, tworzy tabele bazy danych i automatycznie łączy zapytania, mutacje oraz subskrypcje. Dostępny jest również działający przykład dla React Native dla AWS AppSync, który wykorzystuje ten wbudowany schemat (oraz przykład dla React), co pozwala uruchomić zarówno komponenty klienckie, jak i chmurowe w ciągu kilku minut.

Rozpoczęcie pracy jest proste, gdy używasz AWSAppSyncClient, który podłącza się do Apollo Client. AWSAppSyncClient obsługuje bezpieczeństwo i podpisywanie dla twojego interfejsu API GraphQL, funkcjonalność offline oraz proces uzgadniania i negocjacji subskrypcji:

import AWSAppSyncClient from "aws-appsync";
import { Rehydrated } from 'aws-appsync-react';
import { AUTH_TYPE } from "aws-appsync/lib/link/auth-link";

const client = new AWSAppSyncClient({
url: awsconfig.graphqlEndpoint,
region: awsconfig.region,
auth: {type: AUTH_TYPE.API_KEY, apiKey: awsconfig.apiKey}
});

Konsola AppSync udostępnia plik konfiguracyjny do pobrania, który zawiera twój punkt końcowy GraphQL, region AWS i klucz API. Następnie możesz użyć klienta z React Apollo:

const WithProvider = () => (
<ApolloProvider client={client}>
<Rehydrated>
<App />
</Rehydrated>
</ApolloProvider>
);

W tym momencie możesz używać standardowych zapytań GraphQL:

query ListEvents {
listEvents{
items{
__typename
id
name
where
when
description
comments{
__typename
items{
__typename
eventId
commentId
content
createdAt
}
nextToken
}
}
}
}

Powyższy przykład pokazuje zapytanie z przykładowym schematem aplikacji utworzonym przez AppSync. Prezentuje on nie tylko interakcję z DynamoDB, ale także zawiera paginację danych (w tym zaszyfrowanych tokenów) oraz relacje typów między Events i Comments. Ponieważ aplikacja jest skonfigurowana z AWSAppSyncClient, dane są automatycznie utrwalane offline i będą synchronizowane, gdy urządzenia ponownie połączą się z siecią.

Możesz zobaczyć dogłębną analizę technologii klienckiej stojącej za tym oraz demo React Native w tym filmie.

Opinie

Zespół stojący za tymi bibliotekami jest bardzo ciekaw, jak działają one dla Ciebie. Chcemy również usłyszeć, co jeszcze możemy zrobić, aby ułatwić Ci tworzenie aplikacji w React i React Native z wykorzystaniem usług w chmurze. Skontaktuj się z zespołem AWS Mobile na GitHubie w sprawie AWS Amplify lub AWS AppSync.

Implementacja animacji ładowania aplikacji Twittera w React Native

· 9 minut czytania
Eli White
Eli White
Software Engineer @ Meta
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 →

Animacja ładowania w aplikacji Twittera na iOS bardzo mi się podoba.

Gdy aplikacja jest gotowa, logo Twittera rozwija się w przyjemny sposób, odsłaniając aplikację.

Postanowiłem odtworzyć tę animację ładowania za pomocą React Native.


Aby zrozumieć, jak to zbudować, musiałem najpierw rozłożyć animację na części. Najłatwiej dostrzec subtelności, spowalniając ją.

Musimy rozwiązać kilka kluczowych elementów tej animacji.

  1. Skalowanie ptaka (logo).

  2. Podczas powiększania ptaka – odsłanianie aplikacji znajdującej się pod spodem

  3. Lekkie pomniejszenie aplikacji na końcu animacji

Odtworzenie tej animacji zajęło mi sporo czasu.

Początkowo przyjąłem błędne założenie, że niebieskie tło i ptak Twittera stanowią warstwę na wierzchu aplikacji, a podczas powiększania logo stawało się przeźroczyste, odsłaniając aplikację. To podejście nie działa, bo przeźroczyste logo pokazałoby niebieską warstwę, a nie aplikację pod spodem!

Na szczęście dla was, drodzy czytelnicy, oszczędzę wam tych frustracji. W tym poradniku od razu przejdziemy do konkretów!


Prawidłowe rozwiązanie

Zanim przejdziemy do kodu, warto zrozumieć rozkład warstw. Aby zobrazować ten efekt, odtworzyłem go w CodePen (osadzony poniżej), gdzie możecie interaktywnie zobaczyć poszczególne warstwy.

Efekty tworzą trzy główne warstwy. Pierwsza to niebieska warstwa tła. Choć wydaje się być na wierzchu aplikacji, tak naprawdę znajduje się z tyłu.

Następnie mamy jednolitą białą warstwę. Na samym przodzie znajduje się nasza aplikacja.


Kluczowa sztuczka to użycie logo Twittera jako mask, która zakrywa zarówno aplikację, jak i białą warstwę. Nie będę szczegółowo omawiał maskowania — w sieci znajdziecie mnóstwo zasobów na ten temat.

Podstawowa zasada maskowania: nieprzeźroczyste piksele maski odsłaniają zawartość, którą zakrywają, a przeźroczyste piksele maski ją ukrywają.

Logo Twittera służy jako maska dla dwóch warstw: jednolitej białej warstwy i warstwy aplikacji.

Aby odsłonić aplikację, powiększamy maskę, aż przekroczy rozmiar całego ekranu.

Podczas powiększania maski zwiększamy przezroczystość warstwy aplikacji, odsłaniając ją i ukrywając białą warstwę pod spodem. Na koniec efektu: warstwę aplikacji początkowo skalujemy do rozmiaru >1, a następnie zmniejszamy do 1 pod koniec animacji. Potem ukrywamy warstwy nie-aplikacyjne, bo nie będą już widoczne.

Mówi się, że obraz wart jest 1000 słów. A ile słów warta jest interaktywna wizualizacja? Klikajcie przycisk "Next Step", by przejść przez animację. Widok warstw pokazuje perspektywę boczną. Siatka pomaga wizualizować przeźroczyste warstwy.

Czas na React Native

Dobra. Skoro wiemy, co budujemy i jak działa animacja, pora przejść do kodu — czyli tego, po co tu właściwie jesteście.

Kluczowym elementem jest MaskedViewIOS, rdzenny komponent React Native.

import {MaskedViewIOS} from 'react-native';

<MaskedViewIOS maskElement={<Text>Basic Mask</Text>}>
<View style={{backgroundColor: 'blue'}} />
</MaskedViewIOS>;

MaskedViewIOS przyjmuje właściwości maskElement i children. Elementy children są maskowane przez maskElement. Warto zauważyć, że maska nie musi być obrazem – może to być dowolny widok. W powyższym przykładzie efektem będzie wyrenderowanie niebieskiego widoku, który będzie widoczny tylko tam, gdzie znajdują się słowa "Basic Mask" z maskElement. Właśnie stworzyliśmy skomplikowany niebieski tekst.

Chcemy wyrenderować naszą niebieską warstwę, a na wierzchu umieścić naszą maskowaną warstwę aplikacji i białą warstwę z logo Twittera.

{
fullScreenBlueLayer;
}
<MaskedViewIOS
style={{flex: 1}}
maskElement={
<View style={styles.centeredFullScreen}>
<Image source={twitterLogo} />
</View>
}>
{fullScreenWhiteLayer}
<View style={{flex: 1}}>
<MyApp />
</View>
</MaskedViewIOS>;

Da nam to warstwy widoczne poniżej.

Teraz część animowana

Mamy już wszystkie elementy potrzebne do działania, następnym krokiem jest ich animowanie. Aby animacja była płynna, użyjemy Animated API React Native.

Animated pozwala nam deklaratywnie definiować animacje w JavaScript. Domyślnie te animacje działają w JavaScripcie i mówią warstwie natywnej, jakie zmiany wprowadzać w każdej klatce. Mimo że JavaScript będzie próbował aktualizować animację w każdej klatce, prawdopodobnie nie będzie w stanie robić tego wystarczająco szybko, co spowoduje utratę klatek (jank). Tego właśnie nie chcemy!

Animated ma specjalne zachowanie, które pozwala uniknąć tego problemu. Flaga useNativeDriver wysyła definicję animacji z JavaScriptu do warstwy natywnej na początku animacji, pozwalając stronie natywnej przetwarzać aktualizacje bez konieczności komunikacji z JavaScriptem w każdej klatce. Ograniczeniem useNativeDriver jest to, że można animować tylko określony zestaw właściwości, głównie transform i opacity. Nie można animować np. koloru tła za pomocą useNativeDriver – przynajmniej na razie. Z czasem dodamy więcej możliwości, a tymczasem zawsze możesz złożyć PR z brakującymi właściwościami dla swojego projektu, co przysłuży się całej społeczności 😀.

Ponieważ zależy nam na płynności animacji, będziemy działać w ramach tych ograniczeń. Więcej o działaniu useNativeDriver możesz przeczytać w naszym poście na blogu.

Dekonstrukcja naszej animacji

Nasza animacja składa się z 4 elementów:

  1. Powiększenie ptaka, odsłaniając aplikację i jednolitą białą warstwę

  2. Wygaszenie aplikacji (fade in)

  3. Pomniejszenie aplikacji

  4. Ukrycie białej i niebieskiej warstwy po zakończeniu

W Animated mamy dwa główne sposoby definiowania animacji. Pierwszy to Animated.timing, który pozwala określić dokładny czas trwania animacji wraz z krzywą wygładzania ruchu. Drugi to fizyczne API jak Animated.spring. Z Animated.spring podajesz parametry jak tarcie i napięcie sprężyny, pozwalając fizyce sterować animacją.

Mamy wiele animacji, które mają działać równocześnie i są ze sobą ściśle powiązane. Na przykład chcemy, aby aplikacja zaczęła wygasać w trakcie odsłaniania maski. Ponieważ te animacje są tak powiązane, użyjemy Animated.timing z pojedynczą wartością Animated.Value.

Animated.Value to opakowanie wartości natywnej, której Animated używa do śledzenia stanu animacji. Zazwyczaj wystarczy jedna taka wartość dla całej animacji. Komponenty używające Animated przechowują tę wartość w stanie.

Ponieważ myślę o tej animacji jako o krokach występujących w różnych momentach jej trwania, zaczniemy od wartości Animated.Value równej 0 (0% ukończenia), a kończymy na 100 (100% ukończenia).

Początkowy stan naszego komponentu będzie następujący.

state = {
loadingProgress: new Animated.Value(0),
};

Gdy będziemy gotowi rozpocząć animację, każemy Animated animować tę wartość do 100.

Animated.timing(this.state.loadingProgress, {
toValue: 100,
duration: 1000,
useNativeDriver: true, // This is important!
}).start();

Następnie próbuję określić przybliżone wartości dla różnych elementów animacji w poszczególnych etapach. Poniższa tabela przedstawia różne komponenty animacji oraz proponowane wartości w miarę postępu czasu.

Maska z logiem Twittera powinna zaczynać od skali 1, potem lekko się zmniejszyć, by następnie gwałtownie powiększyć. Zatem przy 10% animacji powinna mieć wartość skali około 0.8, by na końcu osiągnąć skalę 70. Wybór 70 był dość arbitralny - musiała być na tyle duża, by ptak całkowicie odsłonił ekran, a 60 okazało się za małe 😀. Co ciekawe, im wyższa wartość, tym szybciej będzie się wydawało, że maska rośnie, bo musi osiągnąć większy rozmiar w tym samym czasie. Ta wartość wymagała kilku prób, by dobrze współgrała z tym logo. Inne rozmiary logo lub urządzeń będą wymagały innej końcowej skali, by zapewnić pełne odsłonięcie ekranu.

Aplikacja powinna pozostać niewidoczna przez dłuższy czas, przynajmniej do momentu, gdy logo Twittera zacznie rosnąć. Bazując na oryginalnej animacji, chcę zacząć ją pokazywać, gdy ptak jest w połowie skali, i w pełni ujawnić dość szybko. Zatem przy 15% zaczynamy ją pokazywać, a przy 30% całej animacji jest już w pełni widoczna.

Skala aplikacji zaczyna się od 1.1 i zmniejsza do normalnej skali pod koniec animacji.

A teraz w kodzie.

To, co zrobiliśmy powyżej, to mapowanie wartości z postępu animacji (w procentach) na wartości poszczególnych elementów. Robimy to w Animated za pomocą .interpolate. Tworzymy 3 różne obiekty stylów - jeden dla każdego elementu animacji - używając wartości interpolowanych na podstawie this.state.loadingProgress.

const loadingProgress = this.state.loadingProgress;

const opacityClearToVisible = {
opacity: loadingProgress.interpolate({
inputRange: [0, 15, 30],
outputRange: [0, 0, 1],
extrapolate: 'clamp',
// clamp means when the input is 30-100, output should stay at 1
}),
};

const imageScale = {
transform: [
{
scale: loadingProgress.interpolate({
inputRange: [0, 10, 100],
outputRange: [1, 0.8, 70],
}),
},
],
};

const appScale = {
transform: [
{
scale: loadingProgress.interpolate({
inputRange: [0, 100],
outputRange: [1.1, 1],
}),
},
],
};

Mając te obiekty stylów, możemy ich użyć podczas renderowania fragmentu widoku z początku wpisu. Pamiętaj, że tylko Animated.View, Animated.Text i Animated.Image mogą używać obiektów stylów opartych na Animated.Value.

const fullScreenBlueLayer = (
<View style={styles.fullScreenBlueLayer} />
);
const fullScreenWhiteLayer = (
<View style={styles.fullScreenWhiteLayer} />
);

return (
<View style={styles.fullScreen}>
{fullScreenBlueLayer}
<MaskedViewIOS
style={{flex: 1}}
maskElement={
<View style={styles.centeredFullScreen}>
<Animated.Image
style={[styles.maskImageStyle, imageScale]}
source={twitterLogo}
/>
</View>
}>
{fullScreenWhiteLayer}
<Animated.View
style={[opacityClearToVisible, appScale, {flex: 1}]}>
{this.props.children}
</Animated.View>
</MaskedViewIOS>
</View>
);

Jupi! Elementy animacji wyglądają teraz tak, jak chcemy. Pozostaje tylko posprzątać niebieską i białą warstwę, które nigdy więcej nie będą widoczne.

Aby wiedzieć, kiedy możemy je usunąć, potrzebujemy znać moment zakończenia animacji. Na szczęście Animated.timing w metodzie .start przyjmuje opcjonalne callbacki wykonywane po zakończeniu animacji.

Animated.timing(this.state.loadingProgress, {
toValue: 100,
duration: 1000,
useNativeDriver: true,
}).start(() => {
this.setState({
animationDone: true,
});
});

Mając w state wartość informującą o zakończeniu animacji, możemy zmodyfikować nasze warstwy.

const fullScreenBlueLayer = this.state.animationDone ? null : (
<View style={[styles.fullScreenBlueLayer]} />
);
const fullScreenWhiteLayer = this.state.animationDone ? null : (
<View style={[styles.fullScreenWhiteLayer]} />
);

Voilà! Animacja działa, a nieużywane warstwy są czyszczone po jej zakończeniu. Odtworzyliśmy animację ładowania aplikacji Twittera!

Chwila, u mnie nie działa!

Spokojnie, drogi czytelniku. Sam nie cierpię, gdy poradniki podają tylko fragmenty kodu bez pełnego źródła.

Ten komponent został opublikowany na npm i jest dostępny na GitHubie jako react-native-mask-loader. Aby przetestować na telefonie, wersja na Expo jest dostępna tutaj:

Dalsza lektura / Zadania dodatkowe

  1. Ta książka to świetne źródło wiedzy o Animated po przeczytaniu dokumentacji React Native.

  2. Oryginalna animacja Twittera przyspiesza odsłanianie maski pod koniec. Spróbuj zmodyfikować loader, używając innej funkcji easingu (lub springa!), by lepiej odwzorować to zachowanie.

  3. Obecna końcowa skala maski jest zakodowana na sztywno i może nie odsłaniać całej aplikacji na tablecie. Obliczanie końcowej skali na podstawie rozmiaru ekranu i obrazu byłoby świetnym PR-em.

Miesięczne podsumowanie React Native #6

· 4 minuty czytania
Tomislav Tenodi
Założyciel Speck
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 →

Comiesięczne spotkania React Native wciąż trwają w pełni! Sprawdź notatkę na dole tego posta, aby poznać terminy kolejnych sesji.

Expo

  • Gratulacje dla Devin Abbott i Houssein Djirdeh z okazji przedpremierowej publikacji książki "Full Stack React Native"! Poprowadzi ona czytelników przez naukę React Native poprzez budowanie kilku małych aplikacji.

  • Wydano pierwszą (eksperymentalną) wersję reason-react-native-scripts, która pomoże łatwo wypróbować ReasonML.

  • Expo SDK 24 zostało wydane! Wykorzystuje React Native 0.51 i zawiera mnóstwo nowych funkcji i ulepszeń: dołączanie obrazów w aplikacjach standalone (brak konieczności cache'owania przy pierwszym ładowaniu!), API do manipulacji obrazami (przycinanie, zmiana rozmiaru, obracanie, odbicie), API do wykrywania twarzy, nowe funkcje kanałów wydań (ustawianie aktywnego wydania dla danego kanału i wycofywanie), panel internetowy do śledzenia budowania aplikacji standalone oraz naprawienie długo istniejącego błędu w implementacji OpenGL dla Androida i wielozadaniowości Androida, by wymienić tylko kilka.

  • Od stycznia przeznaczamy więcej zasobów na React Navigation. Silnie wierzymy, że jest możliwe i pożądane budowanie nawigacji React Native przy użyciu komponentów React i prymitywów takich jak Animated oraz react-native-gesture-handler, i jesteśmy naprawdę podekscytowani niektórymi zaplanowanymi ulepszeniami. Jeśli szukasz możliwości, by przyczynić się do społeczności, sprawdź react-native-maps i react-native-svg — oba projekty mogą skorzystać z pomocy!

Infinite Red

Microsoft

  • Rozpoczęto pull request w celu migracji rdzenia mostka React Native Windows do .NET Standard, co uczyni go efektywnie niezależnym od systemu operacyjnego. Mamy nadzieję, że wiele innych platform .NET Core będzie mogło rozszerzyć mostek własnymi modelami wątkowości, środowiskami uruchomieniowymi JavaScript i UIManagerami (pomyśl o JavaScriptCore, Xamarin.Mac, Linux Gtk# i opcjach Samsung Tizen).

Wix

  • Detox

    • Aby móc skalować testy E2E, chcemy zminimalizować czas spędzany na CI, pracujemy nad wsparciem dla równoległości w Detox.
    • Zgłoszono pull request w celu umożliwienia wsparcia dla niestandardowych wersji buildów, aby lepiej wspierać mocking w testach E2E.
  • DetoxInstruments

    • Praca nad przełomową funkcją DetoxInstruments okazuje się bardzo wymagającym zadaniem. Tworzenie śladu stosu JavaScript w dowolnym momencie wymaga niestandardowej implementacji JSCore obsługującej zawieszanie wątku JS. Testy profilera wewnętrznie w aplikacji Wix ujawniły ciekawe wnioski dotyczące wątku JS.
    • Projekt nadal nie jest wystarczająco stabilny do ogólnego użytku, ale trwają nad nim aktywne prace i mamy nadzieję wkrótce go ogłosić.
  • React Native Navigation

    • Tempo rozwoju wersji 2 znacząco przyspieszyło. Dotychczas tylko jeden programista pracował nad projektem przez 20% swojego czasu, obecnie trzech programistów pracuje nad nim na pełen etat!
  • Wydajność Androida

    • Zastąpienie starego JSCore dołączonego do RN jego najnowszą wersją (szczytową wersją projektu webkitGTK z niestandardową konfiguracją JIT) przyniosło 40% wzrost wydajności wątku JS. Kolejnym krokiem jest kompilacja wersji 64-bitowej. Prace te opierają się na skryptach budujących JSC dla Androida. Aktualny status można śledzić tutaj.

Kolejne spotkania

Trwała dyskusja na temat przekształcenia tych spotkań w dyskusje skupione na jednym konkretnym temacie (np. nawigacja, przenoszenie modułów React Native do oddzielnych repozytoriów, dokumentacja, ...). Wierzymy, że w ten sposób najlepiej przysłużymy się społeczności React Native. Zmiana może nastąpić już podczas kolejnego spotkania. Zachęcamy do podzielenia się na Twitterze tematami, które chcielibyście zobaczyć.

Miesięcznik React Native #5

· 4 minuty czytania
Tomislav Tenodi
Założyciel w Speck
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 →

Kolejne miesięczne spotkanie React Native! Zobaczmy, co robią nasze zespoły.

Callstack

  • Pracowaliśmy nad ciągłą integracją (CI) React Native. Najważniejsze, że migrowaliśmy z Travisa na Circle, zapewniając React Native jednolity, spójny proces CI.

  • Zorganizowaliśmy Hacktoberfest - edycja React Native, gdzie wraz z uczestnikami składaliśmy liczne pull requesty do projektów open source.

  • Kontynuujemy prace nad Haul. W zeszłym miesiącu wydaliśmy dwie nowe wersje, w tym wsparcie dla webpacka 3. Planujemy dodać obsługę CRNA i Expo oraz ulepszyć HMR. Nasz plan rozwoju jest publicznie dostępny w systemie śledzenia problemów. Jeśli chcesz zgłosić sugestie lub opinię, daj nam znać!

Expo

  • Wydano Expo SDK 22 (oparte na React Native 0.49) i zaktualizowano CRNA.

    • Zawiera ulepszone API ekranu startowego, podstawowe wsparcie ARKit, API "DeviceMotion", obsługę SFAuthenticationSession w iOS11 oraz więcej.
  • Twoje snacki mogą teraz zawierać wiele plików JavaScript, a obrazy i inne zasoby możesz przesyłać przeciągając je do edytora.

  • Wspieraliśmy rozwój react-navigation dodając obsługę iPhone'a X.

  • Skupiamy się na wygładzaniu niedoskonałości przy budowaniu dużych aplikacji w Expo. Przykładowo:

    • Wsparcie najwyższej klasy dla wdrażania w wielu środowiskach: staging, produkcja i dowolne kanały. Kanały będą obsługiwać wycofywanie wersji i ustawianie aktywnej wersji dla kanału. Daj znać jeśli chcesz być testerem wczesnej wersji: @expo_io.
    • Pracujemy też nad ulepszeniem infrastruktury budowania samodzielnych aplikacji oraz dodajemy możliwość dołączania obrazów i innych zasobów niebędących kodem, przy zachowaniu możliwości aktualizacji zasobów przez sieć.

Facebook

  • Lepsze wsparcie języków RTL:

    • Wprowadzamy kierunkowo-świadome style:
      • Pozycja:
        • (left|right) → (start|end)
      • Margines:
        • margin(Left|Right) → margin(Start|End)
      • Dopełnienie:
        • padding(Left|Right) → padding(Start|End)
      • Obramowanie:
        • borderTop(Left|Right)Radius → borderTop(Start|End)Radius
        • borderBottom(Left|Right)Radius → borderBottom(Start|End)Radius
        • border(Left|Right)Width → border(Start|End)Width
        • border(Left|Right)Color → border(Start|End)Color
    • Znaczenie "left" i "right" było zamienione w układach RTL dla stylów pozycji, marginesów, dopełnienia i obramowania. W ciągu kilku miesięcy usuniemy to zachowanie - "left" zawsze będzie oznaczać lewą stronę, a "right" prawą. Zmiany łamiące kompatybilność są ukryte pod flagą. Użyj I18nManager.swapLeftAndRightInRTL(false) w komponentach React Native, aby je włączyć.
  • Pracujemy nad typowaniem naszych wewnętrznych modułów natywnych w Flow i wykorzystujemy to do generowania interfejsów w Javie oraz protokołów w ObjC, które muszą implementować natywne implementacje. Mamy nadzieję, że ten system generowania kodu stanie się open source najwcześniej w przyszłym roku.

Infinite Red

  • Nowe narzędzie open source wspierające React Native i inne projekty. Więcej informacji tutaj.

  • Gruntowna modernizacja Ignite przed nową wersją boilerplate (kryptonim: Bowser)

Shoutem

  • Usprawniamy proces rozwoju na platformie Shoutem. Chcemy uspójnić ścieżkę od tworzenia aplikacji do pierwszej niestandardowej ekranu, obniżając próg wejścia dla nowych developerów React Native. Przygotowaliśmy warsztaty testujące nowe funkcje. Ulepszyliśmy również Shoutem CLI pod kątem nowych przepływów.

  • Shoutem UI otrzymało ulepszenia komponentów i poprawki błędów. Sprawdziliśmy też kompatybilność z najnowszymi wersjami React Native.

  • Platforma Shoutem zyskała istotne aktualizacje, a nowe integracje są dostępne w ramach projektu rozszerzeń open source. Cieszymy się widząc aktywny rozwój rozszerzeń Shoutem przez innych developerów. Aktywnie kontaktujemy się z nimi, oferując porady i wsparcie.

Kolejne spotkanie

Kolejna sesja odbędzie się w środę, 6 grudnia 2017. Śmiało daj mi znać na Twitterze, jeśli masz pomysły jak usprawnić rezultaty naszych spotkań.