Przejdź do treści głównej

React Native 0.75 – Obsługa wartości procentowych w układzie, stabilizacja Nowej Architektury, aktualizacje szablonów i inicjalizacji oraz więcej

· 15 minut czytania
Gabriel Donadel Dall'Agnol
Gabriel Donadel Dall'Agnol
Software Engineer @ Expo
Siddharth Kulkarni
Siddharth Kulkarni
Software Engineer @ Coinbase
Thibault Malbranche
Thibault Malbranche
Lead Mobile Engineer @ Brigad
Blake Friedman
Blake Friedman
Software Engineer @ Meta
Riccardo Cipolleschi
Riccardo Cipolleschi
Software Engineer @ Meta
Nicola Corti
Nicola Corti
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 →

Z przyjemnością ogłaszamy wydanie React Native 0.75!

Ta wersja wprowadza kilka nowych funkcji, w tym Yoga 3.1 z obsługą wartości %, poprawki stabilizujące Nową Architekturę oraz rekomendację korzystania z frameworków React Native.

Najważniejsze zmiany

Zmiany łamiące kompatybilność

Najważniejsze zmiany

Yoga 3.1 i ulepszenia układu

Od czasu wydania Yogi w wersji 3.0 w React Native 0.74, kontynuowaliśmy wprowadzanie ulepszeń układu dla waszych aplikacji. React Native 0.75 zawiera Yogę 3.1, a więcej o nowościach możecie przeczytać w oficjalnym wpisie na blogu Yogi.

Jedną z długo wyczekiwanych funkcji jest obsługa wartości % w różnych miejscach, takich jak gaps (odstępy) i translation (przesunięcie).

informacja

Te funkcje są dostępne tylko w Nowej Architekturze. Jeśli chcesz z nich korzystać, rozważ migrację.

Wartości procentowe w odstępach

W wersji 0.75 właściwości gap, columnGap i rowGap, opisane tutaj, obsługują teraz ciąg znaków z wartością %.

Na przykład:

function App(): React.JSX.Element {
return (
<SafeAreaView
style={{
marginTop: 20,
alignItems: 'center',
flex: 1,
rowGap: '20%',
}}>
<View
style={{flex: 1, flexDirection: 'row', columnGap: '10%'}}>
<View
style={{
backgroundColor: 'purple',
width: 100,
height: 100,
}}
/>
<View
style={{
backgroundColor: 'blue',
width: 100,
height: 100,
}}
/>
<View
style={{
backgroundColor: 'green',
width: 100,
height: 100,
}}
/>
</View>
<View
style={{flex: 1, flexDirection: 'row', columnGap: '10%'}}>
<View
style={{
backgroundColor: 'lime',
width: 100,
height: 100,
}}
/>
<View
style={{
backgroundColor: 'yellow',
width: 100,
height: 100,
}}
/>
<View
style={{
backgroundColor: 'orange',
width: 100,
height: 100,
}}
/>
</View>
<View
style={{flex: 1, flexDirection: 'row', columnGap: '10%'}}>
<View
style={{
backgroundColor: 'red',
width: 100,
height: 100,
}}
/>
<View
style={{
backgroundColor: 'violet',
width: 100,
height: 100,
}}
/>
<View
style={{
backgroundColor: 'magenta',
width: 100,
height: 100,
}}
/>
</View>
</SafeAreaView>
);
}

Będzie renderowany w następujący sposób:

AndroidiOS
Android GapsiOS Gaps

Wartości procentowe w przesunięciu

Właściwość transform może teraz również przyjmować wartości % dla przekształceń translate.

Na przykład, poniższy komponent przesunie współrzędną X czerwonego kwadratu o 100% jego szerokości, a współrzędną Y o 100% jego wysokości:

function Translated() {
return (
<SafeAreaView
style={{
marginTop: 20,
flex: 1,
rowGap: '20%',
}}>
<View
style={{
backgroundColor: 'red',
width: 100,
height: 100,
transform: [{translateY: '100%'}, {translateX: '100%'}],
}}
/>
</SafeAreaView>
);
}

Będzie renderowany w następujący sposób:

AndroidiOS
Android TranslationiOS Translation

Stabilizacja Nowej Architektury

Od ogłoszenia Nowej Architektury w fazie Beta na React Conf, wprowadziliśmy liczne poprawki błędów i usprawnienia stabilności.

Naszym celem jest uznanie Nowej Architektury za stabilną w najbliższej przyszłości. Dlatego w ostatnich miesiącach skupiliśmy się na wypełnianiu luk pomiędzy Starą a Nową Architekturą. Przykłady naprawionych błędów i brakujących funkcji to:

  • Naprawa adjustsFontSizeToFit na Androida (#44075)

  • Naprawa działania textAlign z widokami w linii na Androida (#44146)

  • Naprawa przesunięcia linii bazowej tekstu w górę na iOS (#44932)

Wraz z zespołem Expo dodaliśmy również informacje o wsparciu Nowej Architektury w Katalogu React Native, aby od razu było wiadomo, czy biblioteka już ją obsługuje:

Katalog React Native

Zapraszamy również do udziału w ankiecie dotyczącej Nowej Architektury. Ta ankieta jest kluczowa dla zebrania cennych opinii o kolejnych krokach wdrażania Nowej Architektury.

Chcemy też podzielić się naszym wpisem w Grupie Roboczej Nowej Architektury o Obsłudze UIManager w Nowej Architekturze. Ten wpis zawiera przegląd API UIManager na Androida i wyjaśnia, jak może pomóc w migracji zaawansowanych aplikacji i bibliotek.

W tej wersji pojawiło się również nowe API, które jest teraz zalecanym sposobem dostępu do jsi::Runtime.

Dostęp do jsi::Runtime w TurboModules

Dotąd nie było zalecanego sposobu dostępu do jsi::Runtime z modułów natywnych - użytkownicy omijali framework ryzykownymi metodami. W wersji 0.74 wprowadziliśmy eksperymentalne API zapewniające bezpieczny dostęp do jsi::Runtime, a w 0.75 ogłaszamy ich stabilność.

Examples on how to access the jsi::Runtime

On iOS, you can make your Turbo Native Module conform to the protocol RCTTurboModuleWithJSIBindings. You can now implement installJSIBindingsWithRuntime, which will give you thread-safe access to the runtime.

@interface RCTSampleTurbo Module () <RCTTurboModuleWithJSIBindings>
@end

#pragma mark - RCTTurboModuleWithJSIBindings
- (void)installJSIBindingsWithRuntime:(jsi::Runtime &)runtime {
runtime.global().setProperty(
runtime,
"myGlobalFunction",
jsi:: Function::createFromHost Function(...));
}

On Android, you can make your Turbo Native Module conform to the interface TurboModuleWithBindings. You can now implement the JNI method getBindingsInstaller, which will give you thread-safe access to the runtime in C++.

public class SampleTurboModule extends NativeSampleTurboModuleSpec implements TurboModuleWithJSIBindings

@Override
public native BindingsInstallerHolder getBindingsInstaller();
// C++
jni::local_ref<BindingsInstallerHolder::javaobject> SampleTurboModuleJSIBindings::getBindingsInstaller(jni::alias_ref<jni::object> jobj) {
return BindingsInstallerHolder::newObjectCxxArgs(
[](jsi::Runtime& runtime) {
runtime.global().setProperty(
runtime,
“myGlobalFunction”,
jsi::Function::createFromHostFunction(...));
}
);
}

If you’re on the UI thread and you need to access the runtime, we introduced a new API: CallInvoker. It consists of a single method, invokeAsync, that will jump onto the JS thread to safely execute some work using the JS runtime. These APIs are forward compatible.

On iOS, we’ve provided the protocol RCTCallInvokerModule. After conforming to this protocol, our infrastructure will decorate the module with access to the CallInvoker.

@interface RCTSampleTurboModule() <RCTCallInvokerModule>

[self.callInvoker callInvoker].invokeAsync([&](jsi::Runtime& runtime) {
// do stuff on JS thread
}

On Android, the CallInvoker is accessible through the ReactContext in a JNI wrapper called CallInvokerHolder, where you can then call invokeAsync after crossing the JNI boundary.

// Java
public abstract CallInvokerHolder getJSCallInvokerHolder();
// C++
jsCallInvokerHolder->cthis()->getCallInvoker()->invokeAsync([&](jsi::Runtime& rt) {
// do stuff on JS thread
});

Korzystanie z frameworków

Jak ogłosiliśmy na React Conf, zalecanym sposobem budowania aplikacji React Native jest teraz użycie frameworka, takiego jak Expo.

Więcej o tych zaleceniach przeczytasz w naszym poprzednim wpisie: "Używaj frameworka do budowania aplikacji React Native".

Chcemy zapewnić nowym użytkownikom React Native sukces. Uważamy, że frameworki maksymalizują produktywność i oferują najlepsze doświadczenia developerskie przy budowaniu aplikacji.

Aby odzwierciedlić te zalecenia, ta wersja zawiera następujące zmiany:

  • Przenieśliśmy folder /template z pakietu react-native do osobnego repozytorium: react-native-community/template.

  • Wycofujemy polecenie react-native init z dniem 31 grudnia 2024 roku.

Jeśli już używasz frameworka takiego jak Expo, te zmiany Cię nie dotkną. Możesz używać React Native 0.75 z Expo SDK 51 (instrukcje znajdziesz w tym dedykowanym wpisie Expo).

Jeśli nie używasz frameworka lub budujesz własny, zobaczmy jak te zmiany Cię wpłyną.

Przeniesienie szablonu do react-native-community/template

Historycznie, react-native dostarczał folder /template wewnątrz pakietu NPM, który był używany przez Community CLI do tworzenia nowych projektów. To sprawiało, że aktualizacja szablonu była dość powolna, ponieważ każda zmiana wymagała nowej wersji React Native.

Z naszym ostatnim zaleceniem używania frameworków, uznaliśmy że dostarczanie szablonu o określonej konwencji w głównym pakiecie NPM nie jest zgodne z naszą wizją.

Dlatego zdecydowaliśmy się przenieść szablon do pakietu @react-native-community/template.

Ułatwi to społeczności utrzymywanie i rozwijanie szablonu bez konieczności oczekiwania na wydanie React Native przy każdej zmianie. Dodatkowo, przybliża to szablon do Community CLI i ułatwia wszystkim inspekcję oraz zależność od szablonu jako osobnego pakietu.

Ta zmiana powinna być całkowicie przezroczysta dla użytkowników tworzących nowe projekty za pomocą Community CLI. Od teraz, nowe problemy związane z szablonem należy zgłaszać w systemie śledzenia błędów szablonu. Wszystkie narzędzia zależne od szablonu, takie jak upgrade-helper, zostały odpowiednio zaktualizowane i będą działać normalnie.

Wycofywanie react-native init

Podobnie jak w przypadku szablonu, komenda react-native init została dostosowana do nowych zaleceń.

Historycznie, react-native init była domyślną komendą do tworzenia nowych projektów React Native. Jednak w 2024 roku uważamy, że ta komenda nie zapewnia takiego samego doświadczenia jak framework. Dlatego nie polecamy jej już używania - zamiast tego powinieneś używać frameworka takiego jak Expo.

Nadal możesz używać react-native init do tworzenia nowych projektów z Community CLI i szablonem, ale zobaczysz następujące ostrzeżenie:

Ostrzeżenie o wycofaniu

Od 31 grudnia 2024 roku komenda init przestanie tworzyć projekty. Będziesz musiał:

  • Użyć frameworka takiego jak Expo z dedykowaną komendą (np. npx create-expo-app)

  • Wywołać Community CLI bezpośrednio: npx @react-native-community/cli init

Pamiętaj, że react-native config i wszystkie inne komendy poza init będą działać normalnie.

informacja

Aby zapewnić płynniejsze przejście, pakiet react-native@0.75.0 nadal zależy od @react-native-community/cli, ale planujemy usunięcie tej zależności w najbliższej przyszłości.

Poprawa wydajności auto-linkowania

Podczas prac nad aktualizacją komendy init przepisaliśmy logikę auto-linkowania, aby była wydajniejsza. Skutkuje to szybszym budowaniem projektów zarówno na Androidzie, jak i iOS.

W React Native 0.75, jeśli używasz Expo, etap auto-linkowania może działać ~6.5x szybciej na Androidzie i ~1.5x szybciej na iOS. Więcej o tych ulepszeniach przeczytasz tutaj.

Zmiany łamiące kompatybilność

Choć poniższa sekcja może wydawać się obszerna, spodziewamy się że zmiany łamiące kompatybilność dotkną głównie niewielką grupę użytkowników stosujących React Native w zaawansowany sposób.

Przedstawiamy je tutaj dla kompletności i jako odniesienie.

Elementy Touchable w TypeScript nie mogą już być używane jako typy w wyrażeniach generycznych

Komponenty TouchablesOpacity i TouchableHighlights zostały przekształcone na komponenty funkcyjne. Oznacza to, że nie mogą być już używane jako value & type. Na przykład, poniższy kod nie jest już poprawny:

import {TouchableHighlight} from 'react-native';
const ref = useRef<TouchableHighlight>();
// ^^^ TS2749: TouchableHighlight refers to a value, but is being used as a type here.
// Did you mean typeof TouchableHighlight?

Zamiast tego należy użyć wbudowanego typu React React.ElementRef lub alternatywnie typu View:

import {TouchableHighlight} from 'react-native';
const ref1 =
useRef<React.ElementRef<typeof TouchableHighlight>>();
// or
const ref2 = useRef<View>();

Ostatnia wersja wspierająca minSdk 23 i minIOSVersion 13.4

Nie są to zmiany łamiące kompatybilność w wersji 0.75 per se, ale chcemy poinformować, że React Native 0.75 będzie ostatnią wersją wspierającą minSdk 23 (Android 6.0) oraz minIOSVersion 13.4.

Począwszy od React Native 0.76, minimalna wersja SDK będzie wynosić 24 (Android 7.0), a minimalna wersja iOS będzie wynosić 15.1.

Więcej informacji można znaleźć w naszych oficjalnych ogłoszeniach dla Androida oraz dla iOS.

Android: Usunięto JSIModule

com.facebook.react.bridge.JSIModule (source) to interfejs API tymczasowo wprowadzony, aby umożliwić modułom natywnym bezpośredni dostęp do JSI na Androidzie.
Dostęp do tego API został oznaczony jako przestarzały w wersji 0.74. Po weryfikacji nie znaleźliśmy znaczącego wykorzystania tego API w środowisku open source, dlatego usuwamy go w wersji 0.75.
Jako alternatywę możesz użyć Turbo Native Modules.

Android: Menu podręczne przeniesione do osobnego pakietu

W wersji 0.74 przenieśliśmy PopUpMenu dla Androida do osobnego pakietu w przestrzeni @react-native.
W wersji 0.75 usuwamy pozostałe metody nadal obecne w rdzeniu:

  • UIManagerModule.showPopupMenu()

  • UIManagerModule.dismissPopupMenu()

Jako alternatywę prosimy używać komponentu <PopupMenuAndroid />, który znajduje się w pakiecie @react-native/popup-menu-android.

iOS: Zakończono prace nad wycofaniem PushNotificationIOS

W wersji 0.74 oznaczyliśmy jako przestarzałe niektóre interfejsy API modułu PushNotificationIOS.

W wersji 0.75 usunęliśmy te API, aby zakończyć migrację od starszych reprezentacji metadanych powiadomień.

Usunięto następujące interfejsy API:

  + (void)didReceiveLocalNotification:(UILocalNotification *)notification;
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification;

Zamiast tego użyj didReceiveNotification:(UNNotification *)notification.

Community CLI: Usunięcie poleceń ram-bundle i profile-hermes

Ogłaszamy dwie istotne zmiany w Community CLI: usunięcie poleceń ram-bundle oraz profile-hermes.

Polecenie ram-bundle wprowadzono w React Native 0.59, aby umożliwić uruchamianie pakietów poprzez ładowanie ich bezpośrednio do pamięci. Ta funkcjonalność jest obecnie zastąpiona przez Hermes, nasz domyślny silnik JavaScript. Nie powinno się używać polecenia ram-bundle.

Polecenie profile-hermes było narzędziem do profilowania wydajności CPU kodu JavaScript. Wykorzystywało przestarzały format .cpuprofile, który nie jest już obsługiwany w nowszych wersjach Chrome. Ponadto odchodzimy od udostępniania tej funkcjonalności jako osobnego polecenia, podnosząc jakość naszych narzędzi do debugowania. Profilowanie CPU jest teraz dostępne w panelu "Profiler" w Eksperymentalnym Nowym Debugerze (Uwaga: niedostępne przy łączeniu z Hermes z poziomu Chrome).

Inne zmiany łamiące kompatybilność

Ogólne

  • Codegen

    • Drobna zmiana nazw klas i struktur generowanych dla czystych modułów Turbo C++. Usunięto token Cxx z ich nazw
    • Wyliczenia typu float nie są już obsługiwane z powodu możliwych błędów precyzji
    • Generowany jest błąd przy przekazywaniu null w JS do argumentu nie dopuszczającego wartości null w kodzie natywnym
  • Linting

    • Konfiguracja ESLint nie uruchamia już Prettier podczas lintowania
  • C++

    • ScrollViewShadowNode wymaga teraz nowego parametru bool includeTransform w konstruktorze
    • Usunięto executeAsynchronously i executeSynchronously_CAN_DEADLOCK z RuntimeExecutor
    • Zmieniono nazwę JsErrorHandlingFunc na OnJsError w JsErrorHandler.h
    • Zmieniono nazwę handleJsError na OnJsError w handleFatalError.h
    • Usunięto nieużywany import z ReactPrimitives.h
    • Metody LongLivedObjectCollection i LongLivedObject przyjmują teraz parametr Runtime
    • Zmieniono nazwę pliku utils/jsi.h na jsi-utils.h
  • TextInput

    • Usunięto przestarzałą funkcję zwrotną onTextInput
  • Pressability

    • Usunięto metody onLongPressShouldCancelPress_DEPRECATED, onResponderTerminationRequest_DEPRECATED i onStartShouldSetResponder_DEPRECATED

Android

  • ReactViewBackgroundDrawable

    • Oznaczono jako przestarzałe na rzecz CSSBackgroundDrawable. Usunięto również niektóre API z ReactViewBackgroundDrawable i ColorUtil
  • ReactContext

    • ReactContext i ReactApplicationContext są teraz abstrakcyjne. Zamiast nich używaj BridgeReactContext i BridgelessReactContext
    • Usunięto ReactContext.initializeWithInstance(). Używaj BridgeReactInstance
    • Usunięto BridgelessReactContext.getJavaScriptContextHolder(). Używaj BridgelessCatalystInstance
    • Usunięto ReactContext.getRuntimeExecutor(). Używaj BridgelessCatalystInstance
  • Layout

    • Dodano obsługę procentowych wartości przerw flex. Zmienia to parametry metod jak setGap, setRowGap i setColumnGap z float na dynamic
    • Wymagane supportsRTL w Android Manifest
  • Runtime

    • Usunięto ReactJsExceptionHandler z ReactHostImpl
    • Aplikacja musi teraz zwracać główne turbomodule przy niestandardowych szablonach
  • DevSupport

    • Zmieniono DevSupportManagerFactory.create() aby przyjmowała nowy parametr PausedInDebuggerOverlayManager
  • Measurement

    • Usunięto UIManagerModule.measureLayoutRelativeToParent()

iOS

  • Runtime

    • Usunięto [RCTHost getSurfacePresenter] i [RCTHost getModuleRegistry]
    • Usunięto klasę EventPriority - domyślnie używane jest EventPriority::AsynchronousBatched. W przypadku błędów kompilacji usuń wszelkie użycia EventPriority
  • Image

    • Usunięto nieużywane RCTImageLoadingPerfInstrumentationEnabled
  • Error Handling

    • Usunięto dostęp do RCTRedBox przez RCTBridge
  • CocoaPods

    • Zmieniono nazwę BUILD_FROM_SOURCE na RCT_BUILD_HERMES_FROM_SOURCE
    • Zmieniono nazwę React-Codegen na ReactCodegen dla lepszej kompatybilności z use_frameworks i Swift
  • TextInput

    • Usunięto przestarzałą funkcję zwrotną onTextInput

Podziękowania

React Native 0.75 zawiera ponad 1491 commitów od 165 współtwórców. Dziękujemy za całą ciężką pracę!

Dziękujemy wszystkim dodatkowym autorom, którzy pracowali nad dokumentowaniem funkcji w tym poście o wydaniu:

Aktualizacja do wersji 0.75

Do sprawdzenia zmian w kodzie między wersjami React Native w istniejących projektach, oprócz dokumentacji aktualizacji, użyj React Native Upgrade Helper.

Aby utworzyć nowy projekt:

npx @react-native-community/cli@latest init MyProject --version latest

Jeśli używasz Expo, React Native 0.75 będzie obsługiwany w Expo SDK 51 (instrukcje jak zaktualizować React Native w projekcie Expo do wersji 0.75.0 są dostępne w tym dedykowanym poście).

informacja

0.75 to obecnie najnowsza stabilna wersja React Native, a 0.72.x przechodzi do stanu nieobsługiwanego. Więcej informacji znajdziesz w polityce wsparcia React Native. Planujemy opublikować końcową aktualizację końca cyklu życia wersji 0.72 w najbliższym czasie.