Przejdź do treści głównej

Nowa Architektura jest już dostępna

· 21 minut czytania
The React Team
The React Team
@reactjs / @reactnative
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 0.76 z domyślnie włączoną Nową Architekturą jest już dostępny na npm!

W poście o wydaniu wersji 0.76 przedstawiliśmy listę istotnych zmian w tej wersji. W tym artykule przybliżamy Nową Architekturę i jej wpływ na przyszłość React Native.

Nowa Architektura wprowadza pełne wsparcie dla nowoczesnych funkcji Reacta, w tym Suspense, Transitions, automatyczne grupowanie i useLayoutEffect. Dodatkowo zawiera nowe systemy Modułów Natywnych i Komponentów Natywnych, umożliwiające pisanie bezpiecznego typowo kodu z bezpośrednim dostępem do interfejsów natywnych bez użycia mostka.

To wydanie jest efektem całkowitego przepisania React Native, nad którym pracujemy od 2018 roku. Szczególnie zadbaliśmy, aby migracja do Nowej Architektury była stopniowa dla większości aplikacji. W 2021 roku powołaliśmy Grupę Roboczą Nowej Architektury do współpracy ze społecznością nad zapewnieniem płynnego procesu aktualizacji całego ekosystemu React.

Większość aplikacji wdroży React Native 0.76 z podobnym nakładem pracy jak przy innych wydaniach. Najpopularniejsze biblioteki React Native już obsługują Nową Architekturę. Zawiera ona również warstwę automatycznej interoperacyjności zapewniającą wsteczną zgodność z bibliotekami przeznaczonymi dla starej architektury.

W ciągu ostatnich lat nasz zespół publicznie dzielił się wizją Nowej Architektury. Jeśli przegapiłeś te prezentacje, zobacz je tutaj:

Czym jest Nowa Architektura

Nowa Architektura to całkowite przepisanie głównych systemów leżących u podstaw React Native, w tym sposobu renderowania komponentów, komunikacji między abstrakcjami JavaScript i natywnymi oraz planowania zadań między wątkami. Choć większość użytkowników nie musi rozumieć działania tych systemów, zmiany te niosą ulepszenia i nowe możliwości.

W starej architekturze React Native komunikował się z platformą natywną za pomocą asynchronicznego mostka. Aby wyrenderować komponent lub wywołać funkcję natywną, React Native musiał serializować i umieszczać w kolejce wywołania funkcji natywnych przez mostek, które były przetwarzane asynchronicznie. Zaleta tej architektury polegała na tym, że główny wątek nigdy nie był blokowany przez aktualizacje renderowania czy obsługę wywołań modułów natywnych, ponieważ cała praca odbywała się na wątku w tle.

Jednak użytkownicy oczekują natychmiastowej reakcji na interakcje, by aplikacja przypominała natywną. Oznacza to, że niektóre aktualizacje muszą być renderowane synchronicznie w odpowiedzi na działania użytkownika, potencjalnie przerywając trwające renderowanie. Ponieważ stara architektura obsługiwała tylko aktualizacje asynchroniczne, musieliśmy ją przepisać, aby umożliwić zarówno aktualizacje asynchroniczne, jak i synchroniczne.

Dodatkowo, w starej architekturze serializowanie wywołań funkcji przez mostek szybko stawało się wąskim gardłem, szczególnie przy częstych aktualizacjach lub dużych obiektach. To utrudniało aplikacjom stabilne osiąganie 60+ FPS. Występowały też problemy z synchronizacją: gdy warstwa JavaScript i natywna straciły synchronizację, niemożliwe było ich synchroniczne uzgadnianie, co skutkowało błędami takimi jak wyświetlanie pustych obszarów na listach czy wizualne przeskoki interfejsu spowodowane renderowaniem stanów pośrednich.

Wreszcie, ponieważ stara architektura przechowywała pojedynczą kopię interfejsu używając natywnej hierarchii i modyfikowała ją bezpośrednio, układ mógł być obliczany tylko w jednym wątku. To uniemożliwiało przetwarzanie pilnych aktualizacji (jak dane wejściowe użytkownika) oraz synchroniczne odczytywanie układu, np. w celu aktualizacji pozycji dymka narzędziowego w efekcie układu.

Wszystkie te problemy uniemożliwiały właściwe wsparcie współbieżnych funkcji Reacta. Aby je rozwiązać, Nowa Architektura obejmuje cztery główne elementy:

  • Nowy system modułów natywnych

  • Nowy mechanizm renderowania

  • Pętla zdarzeń

  • Usunięcie mostka

Nowy system modułów pozwala rendererowi React Native na synchroniczny dostęp do warstwy natywnej, umożliwiając obsługę zdarzeń, planowanie aktualizacji oraz odczytywanie układu zarówno asynchronicznie, jak i synchronicznie. Nowe moduły natywne są domyślnie ładowane leniwie, co znacząco poprawia wydajność aplikacji.

Nowy mechanizm renderowania obsługuje wiele równoległych drzew na wielu wątkach, co pozwala Reactowi przetwarzać różne priorytety aktualizacji – zarówno na wątku głównym, jak i w tle. Obsługuje też synchroniczne i asynchroniczne odczytywanie układu z wielu wątków, zapewniając płynność interfejsu bez zacinania.

Nowa pętla zdarzeń przetwarza zadania na wątku JavaScript w ściśle określonej kolejności. Pozwala to Reactowi przerywać renderowanie dla obsługi zdarzeń, dzięki czemu pilne akcje użytkownika mają priorytet nad niższymi priorytetami przejść interfejsu. Pętla zdarzeń jest też zgodna ze specyfikacjami webowymi, umożliwiając obsługę funkcji takich jak mikrozadania, MutationObserver czy IntersectionObserver.

Usunięcie mostka przyspiesza uruchamianie aplikacji i umożliwia bezpośrednią komunikację między JavaScript a środowiskiem natywnym, minimalizując koszt przełączania zadań. Poprawia to też raportowanie błędów, debugowanie oraz redukuje awarie spowodowane niezdefiniowanym zachowaniem.

Nowa Architektura jest gotowa do użytku produkcyjnego. Jest już wykorzystywana na dużą skalę w Meta w aplikacji Facebooka i innych produktach. Z sukcesem zastosowaliśmy React Native i Nową Architekturę w aplikacjach Facebooka i Instagrama opracowanych dla naszych urządzeń Quest.

Nasi partnerzy używają Nowej Architektury w produkcji od miesięcy: zobacz studia przypadku Expensify i Kraken, oraz przetestuj Bluesky w ich nowej wersji.

Nowe moduły natywne

Nowy system modułów natywnych to gruntowna przebudowa komunikacji między JavaScript a platformą natywną. Napisany całkowicie w C++, otwiera wiele nowych możliwości:

  • Synchroniczny dostęp do i ze środowiska wykonawczego natywnego

  • Bezpieczeństwo typów między kodem JavaScript a natywnym

  • Współdzielenie kodu między platformami

  • Domyślne leniwe ładowanie modułów

W nowym systemie modułów natywnych JavaScript i warstwa natywna mogą synchronicznie komunikować się przez interfejs JavaScript (JSI), bez asynchronicznego mostka. Oznacza to, że twoje moduły natywne mogą teraz synchronicznie wywołać funkcję, zwrócić wartość i przekazać ją do innej funkcji modułu natywnego.

W starej architekturze, aby obsłużyć odpowiedź z wywołań funkcji natywnych, trzeba było dostarczyć funkcję zwrotną, a zwracana wartość musiała być serializowalna:

// ❌ Sync callback from Native Module
nativeModule.getValue(value => {
// ❌ value cannot reference a native object
nativeModule.doSomething(value);
});

W Nowej Architekturze możesz wykonywać synchroniczne wywołania funkcji natywnych:

// ✅ Sync response from Native Module
const value = nativeModule.getValue();

// ✅ value can be a reference to a native object
nativeModule.doSomething(value);

Dzięki Nowej Architekturze możesz w pełni wykorzystać możliwości natywnej implementacji w C++, zachowując dostęp do niej z poziomu interfejsów API JavaScript/TypeScript. Nowy System Modułów obsługuje moduły napisane w C++, dzięki czemu możesz napisać moduł raz, a będzie on działać na wszystkich platformach - Android, iOS, Windows i macOS. Implementacja modułów w C++ umożliwia dokładniejsze zarządzanie pamięcią i optymalizację wydajności.

Dodatkowo, dzięki Codegen, twoje moduły mogą definiować silnie typowany kontrakt między warstwą JavaScript a warstwą natywną. Z naszego doświadczenia wynika, że błędy typów na styku warstw są jedną z najczęstszych przyczyn awarii w aplikacjach wieloplatformowych. Codegen pozwala przezwyciężyć te problemy, jednocześnie generując za ciebie powtarzalny kod.

Moduły są teraz ładowane leniwie: trafiają do pamięci dopiero wtedy, gdy są rzeczywiście potrzebne, a nie podczas uruchamiania aplikacji. Skraca to czas startu aplikacji i utrzymuje go niskim nawet przy wzroście jej złożoności.

Popularne biblioteki jak react-native-mmkv już odczuły korzyści migracji do nowych Modułów Natywnych:

„Nowe Moduły Natywne znacząco uprościły konfigurację, automatyczne linkowanie i inicjalizację dla react-native-mmkv. Dzięki Nowej Architekturze react-native-mmkv stał się czystym Modułem Natywnym w C++, co pozwala mu działać na każdej platformie. Codegen zapewnia pełne bezpieczeństwo typów w MMKV, rozwiązując długotrwały problem NullPointerReference przez wymuszenie null-safety, a możliwość synchronicznego wywoływania funkcji Modułów Natywnych pozwoliła nam zastąpić niestandardowy dostęp JSI nowym API Modułów Natywnych.”

Marc Rousavy, twórca react-native-mmkv

Nowy Renderer

Całkowicie przepisaliśmy również Natywnego Renderera, co przynosi kilka korzyści:

  • Aktualizacje mogą być renderowane na różnych wątkach z różnymi priorytetami

  • Układ może być odczytywany synchronicznie i na różnych wątkach

  • Renderer jest napisany w C++ i współdzielony na wszystkich platformach

Zaktualizowany Natywny Renderer przechowuje hierarchię widoków w niemutowalnej strukturze drzewa. Oznacza to, że interfejs użytkownika jest przechowywany w sposób uniemożliwiający bezpośrednie zmiany, co pozwala na bezpieczne przetwarzanie aktualizacji między wątkami. Dzięki temu może obsługiwać wiele równoległych drzew, z których każde reprezentuje inną wersję interfejsu. W rezultacie aktualizacje mogą być renderowane w tle bez blokowania UI (np. podczas przejść) lub w głównym wątku (w odpowiedzi na działania użytkownika).

Dzięki obsłudze wielu wątków, React może przerwać aktualizację o niskim priorytecie, by wyrenderować pilną (np. wywołaną przez użytkownika), a następnie wznowić pierwotną aktualizację. Nowy renderer może też odczytywać informacje o układzie synchronicznie i na różnych wątkach. Umożliwia to obliczenia w tle dla aktualizacji o niskim priorytecie i synchroniczne odczyty w razie potrzeby, np. przy pozycjonowaniu dymka narzędzia.

Przepisanie renderera w C++ pozwala na współdzielenie go na wszystkich platformach. Gwarantuje to, że ten sam kod działa na iOS, Android, Windows, macOS i innych platformach obsługiwanych przez React Native, zapewniając spójne możliwości renderowania bez konieczności ponownej implementacji.

To znaczący krok w kierunku naszej Wizji Wielu Platform. Na przykład, optymalizacja View Flattening była dotąd dostępna tylko na Androidzie. Nowy renderer ze współdzielonym rdzeniem w C++ przenosi tę funkcję na iOS. Ta optymalizacja działa automatycznie bez konfiguracji - jest darmowym bonusem współdzielonego renderera.

Dzięki tym zmianom React Native w pełni obsługuje teraz funkcje Concurrent React jak Suspense i Transitions, ułatwiając budowanie złożonych interfejsów szybko reagujących na działania użytkownika bez zacinania, opóźnień czy wizualnych przeskoków. W przyszłości wykorzystamy te możliwości do wprowadzenia dalszych ulepszeń wbudowanych komponentów takich jak FlatList i TextInput.

Popularne biblioteki takie jak Reanimated już korzystają z nowego renderera:

„Reanimated 4, obecnie w rozwoju, wprowadza nowy silnik animacji działający bezpośrednio z nowym rendererem, co umożliwia obsługę animacji i zarządzanie układem między różnymi wątkami. Projekt nowego renderera naprawdę umożliwia tworzenie tych funkcji bez polegania na licznych obejściach. Co więcej, dzięki implementacji w C++ i współdzieleniu między platformami, duże części Reanimated można napisać raz, redukując problemy specyficzne dla platform, minimalizując bazę kodu i upraszczając adopcję dla platform spoza głównego drzewa.”

Krzysztof Magiera, twórca Reanimated

Pętla zdarzeń

Nowa architektura pozwoliła nam wdrożyć dobrze zdefiniowany model przetwarzania pętli zdarzeń, jak opisano w tym RFC. Ten RFC opiera się na specyfikacjach Standardu HTML i opisuje, jak React Native powinien wykonywać zadania na wątku JavaScript.

Wdrożenie dobrze zdefiniowanej pętli zdarzeń zamyka luki między React DOM a React Native: zachowanie aplikacji React Native jest teraz bliższe zachowaniu aplikacji React DOM, co ułatwia naukę raz i pisanie wszędzie.

Pętla zdarzeń przynosi wiele korzyści React Native:

  • Możliwość przerywania renderowania w celu przetworzenia zdarzeń i zadań

  • Bliższe dopasowanie do specyfikacji webowych

  • Podstawa dla większej liczby funkcji przeglądarki

Dzięki pętli zdarzeń React może przewidywalnie porządkować aktualizacje i zdarzenia. To pozwala przerwać aktualizację o niskim priorytecie pilnym zdarzeniem użytkownika, a nowy renderer umożliwia niezależne renderowanie tych aktualizacji.

Pętla zdarzeń również dostosowuje zachowanie zdarzeń i zadań takich jak timery do specyfikacji webowych, co oznacza że React Native działa bardziej tak, jak użytkownicy są przyzwyczajeni w sieci, i pozwala na lepsze współdzielenie kodu między React DOM a React Native.

Pozwala również na implementację bardziej zgodnych funkcji przeglądarki jak mikrozadania, MutationObserver i IntersectionObserver. Te funkcje nie są jeszcze gotowe do użycia w React Native, ale pracujemy nad ich wprowadzeniem w przyszłości.

Wreszcie, pętla zdarzeń i zmiany w nowym rendererze umożliwiające synchroniczne odczytywanie układu pozwalają React Native dodać pełne wsparcie dla useLayoutEffect do synchronicznego odczytywania informacji o układzie i aktualizowania UI w tej samej klatce. To pozwala poprawnie pozycjonować elementy przed ich wyświetleniem użytkownikowi.

Więcej szczegółów znajdziesz w sekcji useLayoutEffect.

Usuwanie mostka

W nowej architekturze całkowicie usunęliśmy zależność React Native od mostka, zastępując go bezpośrednią, wydajną komunikacją między JavaScript a kodem natywnym przy użyciu JSI:

Usunięcie mostka poprawia czas uruchamiania dzięki unikaniu jego inicjalizacji. Na przykład w starej architekturze, aby udostępnić globalne metody w JavaScript, musieliśmy inicjalizować moduł przy starcie aplikacji, powodując niewielkie opóźnienie:

// ❌ Slow initialization
import {NativeTimingModule} from 'NativeTimingModule';
global.setTimeout = timer => {
NativeTimingModule.setTimeout(timer);
};

// App.js
setTimeout(() => {}, 100);

W nowej architekturze możemy bezpośrednio wiązać metody z C++:

// ✅ Initialize directly in C++
runtime.global().setProperty(runtime, "setTimeout", createTimer);
// App.js
setTimeout(() => {}, 100);

Przepisanie poprawia również raportowanie błędów, szczególnie dla awarii JavaScript przy uruchamianiu, i redukuje awarie spowodowane niezdefiniowanym zachowaniem. Jeśli wystąpią awarie, nowe React Native DevTools upraszczają debugowanie i obsługują nową architekturę.

Mostek pozostaje dla kompatybilności wstecznej, aby wspierać stopniową migrację do nowej architektury. W przyszłości całkowicie usuniemy kod mostka.

Stopniowa migracja

Oczekujemy, że większość aplikacji może zaktualizować do 0.76 z takim samym wysiłkiem jak w przypadku każdej innej wersji.

Po aktualizacji do wersji 0.76 Nowa Architektura i React 18 są domyślnie włączone. Jednak aby korzystać z funkcji współbieżnych i w pełni wykorzystać możliwości Nowej Architektury, Twoja aplikacja i biblioteki będą wymagały stopniowej migracji do pełnego wsparcia Nowej Architektury.

Podczas pierwszej aktualizacji Twoja aplikacja będzie działać na Nowej Architekturze z automatyczną warstwą interoperacyjności ze starą architekturą. Dla większości aplikacji będzie to działać bez żadnych zmian, ale istnieją znane ograniczenia warstwy interoperacyjności, ponieważ nie obsługuje ona dostępu do niestandardowych węzłów cieni (Shadow Nodes) ani funkcji współbieżnych.

Aby używać funkcji współbieżnych, aplikacje muszą zostać zaktualizowane do obsługi Concurrent React poprzez przestrzeganie Zasad Reacta. Aby zmigrować kod JavaScript do Reacta 18 i jego semantyki, postępuj zgodnie z przewodnikiem aktualizacji do Reacta 18.

Ogólna strategia polega na uruchomieniu aplikacji na Nowej Architekturze bez uszkodzenia istniejącego kodu. Następnie możesz stopniowo migrować aplikację we własnym tempie. Dla nowych ekranów, gdzie wszystkie moduły zostały zmigrowane do Nowej Architektury, możesz od razu korzystać z funkcji współbieżnych. Dla istniejących ekranów możesz potrzebować rozwiązania pewnych problemów i migracji modułów przed dodaniem funkcji współbieżnych.

Współpracowaliśmy z najpopularniejszymi bibliotekami React Native, aby zapewnić wsparcie dla Nowej Architektury. Ponad 850 bibliotek jest już kompatybilnych, w tym wszystkie biblioteki z ponad 200 tys. pobrań tygodniowo (~10% pobieranych bibliotek). Kompatybilność bibliotek z Nową Architekturą możesz sprawdzić na stronie reactnative.directory:

Więcej szczegółów dotyczących aktualizacji znajdziesz w sekcji Jak przeprowadzić aktualizację poniżej.

Nowe funkcje

Nowa Architektura obejmuje pełne wsparcie dla Reacta 18, funkcji współbieżnych i useLayoutEffect w React Native. Pełną listę funkcji Reacta 18 znajdziesz w wpisie na blogu Reacta 18.

Przejścia

Przejścia to nowa koncepcja w React 18, która rozróżnia aktualizacje pilne i niepilne.

  • Aktualizacje pilne odzwierciedlają bezpośrednią interakcję, jak pisanie i naciskanie.

  • Aktualizacje przejściowe zmieniają interfejs użytkownika z jednego widoku na inny.

Pilne aktualizacje wymagają natychmiastowej reakcji, zgodnej z naszymi intuicjami o zachowaniu obiektów fizycznych. Jednak przejścia są inne, ponieważ użytkownik nie oczekuje zobaczenia każdej pośredniej wartości na ekranie. W Nowej Architekturze React Native potrafi oddzielnie renderować aktualizacje pilne i przejściowe.

Zazwyczaj dla najlepszego doświadczenia użytkownika pojedyncze działanie użytkownika powinno skutkować zarówno aktualizacją pilną, jak i niepilną. Podobnie jak w ReactDOM, zdarzenia takie jak press lub change są traktowane jako pilne i renderowane natychmiast. Możesz użyć API startTransition wewnątrz zdarzenia wejściowego, aby poinformować Reacta, które aktualizacje są "przejściami" i mogą być odłożone na później:

import {startTransition} from 'react';

// Urgent: Show the slider value
setCount(input);

// Mark any state updates inside as transitions
startTransition(() => {
// Transition: Show the results
setNumberOfTiles(input);
});

Rozdzielenie zdarzeń pilnych od przejść pozwala na bardziej responsywny interfejs użytkownika i bardziej intuicyjne doświadczenie.

Oto porównanie starej architektury bez przejść i nowej architektury z przejściami. Wyobraź sobie, że każdy kafelek nie jest trywialnym widokiem z kolorem tła, ale bogatym komponentem zawierającym obrazy i inne elementy kosztowne w renderowaniu. Po użyciu useTransition unikasz przeciążania aplikacji aktualizacjami i opóźnień.

A video demonstrating an app rendering many views (tiles) according to a slider input. The views are rendered in batches as the slider is quickly adjusted from 0 to 1000.
Before: rendering tiles without marking it as a transition.
A video demonstrating an app rendering many views (tiles) according to a slider input. The views are rendered in batches as the slider is quickly adjusted from 0 to 1000. There are less batch renders in comparison to the next video.
After: rendering tiles with transitions to interrupt in-progress renders of stale state.

Więcej informacji znajdziesz w sekcji Obsługa współbieżnego renderowania i funkcji.

Automatyczne grupowanie

Po aktualizacji do Nowej Architektury skorzystasz z automatycznego grupowania dostępnego w React 18.

Automatyczne grupowanie pozwala Reactowi zbierać więcej aktualizacji stanu podczas renderowania, aby uniknąć wyświetlania stanów pośrednich. To sprawia, że React Native działa szybciej i jest mniej podatny na opóźnienia, bez dodatkowego kodu od programisty.

A video demonstrating an app rendering many views according to a slider input. The slider value is adjusted from 0 to 1000 and the UI slowly catches up to rendering 1000 views.
Before: rendering frequent state updates with legacy renderer.
A video demonstrating an app rendering many views according to a slider input. The slider value is adjusted from 0 to 1000 and the UI resolves to 1000 views faster than the previous example, without as many intermediate states.
After: rendering frequent state updates with automatic batching.

W starej architekturze renderowanych jest więcej stanów pośrednich, a interfejs użytkownika aktualizuje się nawet po zatrzymaniu suwaka. Nowa Architektura renderuje mniej stanów pośrednich i kończy renderowanie znacznie szybciej dzięki automatycznemu grupowaniu aktualizacji.

Więcej informacji znajdziesz w sekcji Obsługa współbieżnego renderowania i funkcji.

useLayoutEffect

Bazując na pętli zdarzeń i możliwości synchronicznego odczytu układu, w Nowej Architekturze dodaliśmy pełną obsługę useLayoutEffect w React Native.

W starej architekturze do odczytu informacji o układzie widoku (który był asynchroniczny) trzeba było używać asynchronicznego zdarzenia onLayout. W rezultacie występowała co najmniej jedna klatka z nieprawidłowym układem, dopóki układ nie został odczytany i zaktualizowany, powodując problemy jak nieprawidłowe pozycjonowanie dymków:

// ❌ async onLayout after commit
const onLayout = React.useCallback(event => {
// ❌ async callback to read layout
ref.current?.measureInWindow((x, y, width, height) => {
setPosition({x, y, width, height});
});
}, []);

// ...
<ViewWithTooltip
onLayout={onLayout}
ref={ref}
position={position}
/>;

Nowa Architektura rozwiązuje ten problem, umożliwiając synchroniczny dostęp do informacji o układzie w useLayoutEffect:

// ✅ sync layout effect during commit
useLayoutEffect(() => {
// ✅ sync call to read layout
const rect = ref.current?.getBoundingClientRect();
setPosition(rect);
}, []);

// ...
<ViewWithTooltip ref={ref} position={position} />;

Ta zmiana pozwala odczytać informacje o układzie synchronicznie i zaktualizować UI w tej samej klatce, umożliwiając prawidłowe pozycjonowanie elementów zanim zostaną wyświetlone użytkownikowi:

A view that is moving to the corners of the viewport and center with a tooltip rendered either above or below it. The tooltip is rendered after a short delay after the view moves
In the old architecture, layout was read asynchronously in onLayout, causing the position of the tooltip to be delayed.
A view that is moving to the corners of the viewport and center with a tooltip rendered either above or below it. The view and tooltip move in unison.
In the New Architecture, layout can be read in useLayoutEffect synchronously, updating the tooltip position before displaying.

Więcej informacji znajdziesz w dokumentacji Synchroniczny układ i efekty.

Pełna obsługa Suspense

Suspense pozwala deklaratywnie określić stan ładowania dla części drzewa komponentów, jeśli nie jest jeszcze gotowa do wyświetlenia:

<Suspense fallback={<Spinner />}>
<Comments />
</Suspense>

Kilka lat temu wprowadziliśmy ograniczoną wersję Suspense, a React 18 dodał pełne wsparcie. Do tej pory React Native nie obsługiwał współbieżnego renderowania dla Suspense.

Nowa Architektura obejmuje pełne wsparcie dla Suspense wprowadzonego w React 18. Oznacza to, że możesz teraz używać Suspense w React Native do obsługi stanów ładowania komponentów, a zawartość w stanie zawieszenia będzie renderowana w tle podczas wyświetlania stanu ładowania, nadając wyższy priorytet interakcjom użytkownika z widoczną zawartością.

Więcej informacji w RFC dla Suspense w React 18.

Jak przeprowadzić aktualizację

Aby zaktualizować do wersji 0.76, postępuj zgodnie z instrukcjami w wpisie o wydaniu. Ponieważ to wydanie obejmuje też aktualizację do Reacta 18, musisz również postępować zgodnie z przewodnikiem aktualizacji React 18.

Te kroki powinny wystarczyć większości aplikacjom do aktualizacji do Nowej Architektury dzięki warstwie interoperacyjności ze starą architekturą. Jednak aby w pełni wykorzystać Nową Architekturę i zacząć używać funkcji współbieżnych, musisz zmigrować własne Nativne Moduły i Nativne Komponenty do obsługi nowych API.

Bez migracji własnych Nativnych Modułów nie skorzystasz z zalet współdzielonego C++, synchronicznych wywołań metod ani bezpieczeństwa typów z codegen. Bez migracji Nativnych Komponentów nie będziesz mógł używać funkcji współbieżnych. Zalecamy migrację wszystkich Nativnych Komponentów i Nativnych Modułów do Nowej Architektury tak szybko, jak to możliwe.

uwaga

W przyszłym wydaniu usuniemy warstwę interoperacyjności i moduły będą musiały obsługiwać Nową Architekturę.

Aplikacje

Jeśli jesteś programistą aplikacji, aby w pełni obsługiwać Nową Architekturę, musisz zaktualizować swoje biblioteki, własne Nativne Komponenty i własne Nativne Moduły do pełnej kompatybilności.

Współpracowaliśmy z najpopularniejszymi bibliotekami React Native, aby zapewnić wsparcie dla Nowej Architektury. Kompatybilność bibliotek możesz sprawdzić na stronie reactnative.directory.

Jeśli którakolwiek z bibliotek, od których zależy twoja aplikacja, nie jest jeszcze kompatybilna, możesz:

  • Otwórz issue w repozytorium biblioteki i poproś autora o migrację do Nowej Architektury.

  • Jeśli biblioteka nie jest utrzymywana, rozważ alternatywne biblioteki oferujące te same funkcje.

  • Zrezygnuj z Nowej Architektury do czasu migracji tych bibliotek.

Jeśli twoja aplikacja zawiera niestandardowe moduły natywne (Native Modules) lub komponenty natywne (Native Components), spodziewamy się, że będą działać poprawnie dzięki naszej warstwie interoperacyjności. Zalecamy jednak aktualizację do nowych API modułów i komponentów natywnych, aby w pełni wspierać Nową Architekturę i korzystać z funkcji współbieżnych.

Aby zmigrować moduły i komponenty do Nowej Architektury, postępuj zgodnie z tymi przewodnikami:

Biblioteki

Jeśli jesteś opiekunem biblioteki, najpierw przetestuj jej działanie z warstwą interoperacyjności. Jeśli nie działa, zgłoś problem w Grupie Roboczej Nowej Architektury.

Aby w pełni wspierać Nową Architekturę, zalecamy migrację biblioteki do nowych API modułów i komponentów natywnych najszybciej jak to możliwe. Pozwoli to użytkownikom twojej biblioteki w pełni wykorzystać możliwości Nowej Architektury i obsługiwać funkcje współbieżne.

Aby zmigrować moduły i komponenty, postępuj zgodnie z tymi przewodnikami:

Rezygnacja

Jeśli z jakiegokolwiek powodu Nowa Architektura nie działa poprawnie w twojej aplikacji, zawsze możesz tymczasowo z niej zrezygnować, aż będziesz gotowy ją ponownie włączyć.

Aby zrezygnować z Nowej Architektury:

  • Na Androida zmodyfikuj plik android/gradle.properties i wyłącz flagę newArchEnabled:
-newArchEnabled=true
+newArchEnabled=false
  • Na iOS możesz ponownie zainstalować zależności, wykonując polecenie:
RCT_NEW_ARCH_ENABLED=0 bundle exec pod install

Podziękowania

Dostarczenie Nowej Architektury społeczności open-source wymagało ogromnego wysiłku i kilku lat badań oraz rozwoju. Chcemy podziękować obecnym i byłym członkom zespołu React, którzy pomogli osiągnąć ten rezultat.

Jesteśmy też niezmiernie wdzięczni wszystkim partnerom, którzy współpracowali z nami przy tym projekcie. Szczególne podziękowania dla:

  • Expo za wczesne wdrożenie Nowej Architektury i wsparcie migracji popularnych bibliotek

  • Software Mansion za utrzymywanie kluczowych bibliotek, ich wczesną migrację oraz pomoc w diagnozowaniu i rozwiązywaniu problemów

  • Callstack za utrzymywanie kluczowych bibliotek, ich wczesną migrację oraz wsparcie przy tworzeniu Community CLI

  • Microsoft za implementację Nowej Architektury dla react-native-windows i react-native-macos oraz innych narzędzi deweloperskich

  • Expensify, Kraken, Bluesky i Brigad za pionierskie wdrażanie Nowej Architektury i zgłaszanie problemów, co pozwoliło nam je naprawić dla wszystkich

  • Wszystkim niezależnym opiekunom bibliotek i programistom, którzy przyczynili się do powstania Nowej Architektury poprzez testowanie, naprawianie problemów oraz zadawanie pytań w niejasnych kwestiach, dzięki czemu mogliśmy je wyjaśnić.