React Native 0.74 - Yoga 3.0, Bridgeless New Architecture i więcej
Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt. Znalazłeś błąd? Zgłoś problem →
Dziś wydajemy React Native 0.74! Ta wersja wprowadza Yoga 3.0, domyślną opcję Bridgeless w ramach Nowej Architektury, zbiorcze aktualizacje onLayout (Nowa Architektura) oraz Yarn 3 jako domyślny menedżer pakietów dla nowych projektów.
Usuwamy również przestarzałe API, w tym usunięcie PropTypes oraz zmiany łamiące kompatybilność w PushNotificationIOS. W przypadku Androida, SDK 23 (Android 6.0) jest teraz minimalną obsługiwaną wersją.
Najważniejsze zmiany
Zmiany łamiące kompatybilność
Najważniejsze zmiany
Yoga 3.0
Nowe zachowania układu
React Native 0.74 zawiera Yoga 3.0, najnowszą wersję naszego silnika układu. Yoga 3.0 poprawia układ poprzez zwiększenie przewidywalności stylowania oraz obsługuje renderowanie komponentów napisanych dla webu.
React Native nadal celowo zachowuje niektóre niepoprawne zachowania układu, gdyż naprawienie ich wpłynęłoby znacząco na wiele istniejących komponentów. W przyszłych wersjach React Native będzie możliwe bardziej szczegółowe konfigurowanie zgodności układu.
React Native wcześniej zamieniał miejscami krawędzie left/right (oraz start/end) przy ustawianiu margin, padding lub border w kontenerach z row-reverse. Teraz zachowanie tych właściwości jest zgodne z zachowaniem na stronach internetowych. Kod, który wcześniej polegał na odwróconych krawędziach, może wymagać aktualizacji, aby zachować poprawne renderowanie.
| Style | Before | After |
|---|---|---|
|
Obsługa align-content: 'space-evenly'
Yoga 3.0 wprowadza obsługę alignContent: 'space-evenly'. space-evenly rozkłada linie w kontenerze flex z wieloma liniami, używając równomiernie rozmieszczonych odstępów między liniami oraz krawędziami kontenera.

Obsługa position: 'static'
position: 'static' jest obsługiwane tylko w Nowej Architekturze.
Elementy oznaczone jako position: 'static' nie mogą być przesuwane i nie są brane pod uwagę przy określaniu kontenera blokowego dla elementów z pozycją absolutną. Pozwala to pozycjonować element względem przodka, który nie jest jego bezpośrednim rodzicem.
|
Zwróć uwagę, jak zielony <View> deklaruje left i top, a pozycjonowany jest względem niebieskiego <View>, a nie swojego rodzica.
React Native nadal domyślnie używa position: 'relative', gdy nie ustawiono position.
Nowa Architektura: Bridgeless domyślnie
W tym wydaniu ustawiamy tryb Bridgeless jako domyślny, gdy włączona jest Nowa Architektura. Więcej o przejściu na Bridgeless jako domyślny tryb możesz przeczytać w tym poście. Aby ułatwić przejście, udoskonaliliśmy warstwy interoperacyjne dla Bridgeless i współpracowaliśmy z wieloma bibliotekami, aby zapewnić ich działanie w Bridgeless od pierwszego dnia.
Bridgeless to nie jedyna warstwa interoperacyjna, nad którą pracowaliśmy: udoskonaliliśmy także warstwy interoperacyjne Nowego Renderera. Najciekawsze jest to, że są teraz domyślnie włączone - nie musisz wskazywać komponentów, które mają przez nie przechodzić! Więcej informacji znajdziesz tutaj.
Jeśli chcesz dowiedzieć się więcej o Nowej Architekturze, dokumentację znajdziesz w repozytorium react-native-new-architecture. Gdy Nowa Architektura stanie się domyślna, te informacje zostaną włączone do reactnative.dev.
Nowa Architektura: Zgrupowane aktualizacje onLayout
Aktualizacje stanu w callbackach onLayout są teraz grupowane. Wcześniej każda aktualizacja stanu w zdarzeniu onLayout powodowała nowe zatwierdzenie renderowania.
function MyComponent(props) {
const [state1, setState1] = useState(false);
const [state2, setState2] = useState(false);
return (
<View>
<View
onLayout={() => {
setState1(true);
}}>
<View
onLayout={() => {
// When this event is executed, state1's new value is no longer observable here.
setState2(true);
}}>
</View>
</View>
);
}
W wersji 0.74 aktualizacje setState1 i setState2 są grupowane razem. To zachowanie jest oczekiwane w React i pozwala na mniejszą liczbę ponownych renderowań.
Ta zmiana może zepsuć kod, który opierał się na niegrupowanych aktualizacjach stanu. Konieczne będzie przepisanie takiego kodu przy użyciu funkcji aktualizujących lub ekwiwalentnych rozwiązań.
Yarn 3 dla nowych projektów
Yarn 3 jest teraz domyślnym menedżerem pakietów JavaScript dla nowych projektów inicjowanych przez React Native Community CLI.
Yarn 3.x będzie używany z opcją nodeLinker: node-modules, zapewniającą kompatybilność z bibliotekami React Native. Zastępuje to Yarn Classic (1.x, przestarzały) jako poprzednie domyślne rozwiązanie. Aby zaktualizować Yarn w istniejącej aplikacji, skorzystaj z tego przewodnika.
$ yarn --help
━━━ Yarn Package Manager - 3.6.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
$ yarn <command>
Community CLI obsługuje także inicjowanie projektów z innymi menedżerami pakietów poprzez flagę --pm (więcej informacji).
Zmiany łamiące kompatybilność
Nowe minimalne wymaganie SDK dla Androida (Android 6.0)
React Native 0.74 wymaga minimalnej wersji Android SDK 23 (Android 6.0). Poprzednio było to Android 5.0 (API 21). Kontekst tej zmiany opisaliśmy tutaj.
Bonus: redukcja rozmiaru aplikacji na Androida
Podniesienie minimalnego SDK wraz z kilkoma ulepszeniami w natywnej kompilacji pozwoliło znacznie zmniejszyć rozmiar aplikacji na urządzeniach użytkowników.
Np. nowo utworzona aplikacja w React Native 0.74 zajmuje o ~13% mniej miejsca na urządzeniu, co daje oszczędność ~4MB.

Usunięcie przestarzałych PropTypes
Przed wersją 0.74 React Native dostarczał PropTypes - API zdeprecjonowane od React 15.5 w 2017 roku! Teraz usuwamy wszystkie wbudowane PropTypes, redukując rozmiar aplikacji (26.4kB w zminimalizowanym bundle) i obciążenie pamięci.
Usunięto następujące właściwości PropTypes: Image.propTypes, Text.propTypes, TextInput.propTypes, ColorPropType, EdgeInsetsPropType, PointPropType, ViewPropTypes (zobacz commit).
Jeśli Twoja aplikacja lub biblioteka używa PropTypes, zalecamy migrację do systemu typów jak TypeScript.
Zmiany API w PushNotificationIOS (zdeprecjonowane)
W React Native 0.74 podejmujemy kroki ku usunięciu przestarzałej biblioteki PushNotificationIOS. Zmiany w tej wersji koncentrują się na usunięciu referencji do starszych iOS API. PushNotificationIOS został zmigrowany na framework User Notifications Apple'a i udostępnia nowe API do planowania i obsługi powiadomień.
W kolejnej wersji (0.75) planujemy całkowite usunięcie tej biblioteki z rdzenia React Native i przeniesienie do pakietu społecznościowego @react-native-community/push-notification-ios. Jeśli nadal korzystasz z PushNotificationIOS, musisz przeprowadzić migrację przed następnym wydaniem.
Zmiany API
Callback didRegisterUserNotificationSettings: w RCTPushNotificationManager był nieużywany i został usunięty.
Następujące callbacki w RCTPushNotificationManager zostały oznaczone jako przestarzałe i zostaną usunięte w wersji 0.75:
+ (void)didReceiveLocalNotification:(UILocalNotification *)notification;
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification;
Aby pobrać powiadomienie, które uruchomiło aplikację za pomocą getInitialNotification(), musisz teraz jawnie ustawić initialNotification w RCTPushNotificationManager:
[RCTPushNotificationManager setInitialNotification:response.notification];
Po stronie JavaScript zmieniły się właściwości w Notification. alertAction i repeatInterval są teraz przestarzałe i zostaną usunięte w wersji 0.75:
type Notification = {
...
// NEW: Seconds from now to display the notification.
fireIntervalSeconds?: ?number,
// CHANGED: Used only for scheduling notifications. Will be null when
// retrieving notifications using `getScheduledLocalNotifications` or
// `getDeliveredNotifications`.
soundName?: ?string,
// DEPRECATED: This was used for iOS's legacy UILocalNotification.
alertAction?: ?string,
// DEPRECATED: Use `fireDate` or `fireIntervalSeconds` instead.
repeatInterval?: ?string,
};
Wreszcie, nieużywany parametr handler w PushNotificationIOS.removeEventListener został usunięty.
💡 How to Migrate
iOS
Your AppDelegate will need to implement UNUserNotificationCenterDelegate. This should be done on app startup in application:willFinishLaunchingWithOptions: or application:didFinishLaunchingWithOptions: (see Apple Docs for more details).
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
return YES;
}
Implement userNotificationCenter:willPresentNotification:withCompletionHandler:, which is called when a notification arrives and the app is in the foreground. Use the completionHandler to determine if the notification will be shown to the user and notify RCTPushNotificationManager accordingly:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
// This will trigger 'notification' and 'localNotification' events on PushNotificationIOS
[RCTPushNotificationManager didReceiveNotification:notification];
// Decide if and how the notification will be shown to the user
completionHandler(UNNotificationPresentationOptionNone);
}
To handle when a notification is tapped, implement userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:. Note that if you set foreground notifications to be shown in userNotificationCenter:willPresentNotification:withCompletionHandler:, you should only notify RCTPushNotificationManager in one of these callbacks.
If the tapped notification resulted in app launch, call setInitialNotification:. If the notification was not previously handled by userNotificationCenter:willPresentNotification:withCompletionHandler:, call didReceiveNotification: as well:
- (void) userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler
{
// This condition passes if the notification was tapped to launch the app
if ([response.actionIdentifier isEqualToString:UNNotificationDefaultActionIdentifier]) {
// Allow the notification to be retrieved on the JS side using getInitialNotification()
[RCTPushNotificationManager setInitialNotification:response.notification];
}
// This will trigger 'notification' and 'localNotification' events on PushNotificationIOS
[RCTPushNotificationManager didReceiveNotification:response.notification];
completionHandler();
}
Finally, delete the following methods and adapt the logic into the callbacks above which will be called instead:
application:didReceiveLocalNotification:[deprecated]application:didReceiveRemoteNotification:[deprecated]application:didReceiveRemoteNotification:fetchCompletionHandler:[not deprecated, but is superseded by theUNUserNotificationCenterDelegatemethods]
Delete any usages of application:didRegisterUserNotificationSettings: and RCTPushNotificationManager’s corresponding didRegisterUserNotificationSettings: as well.
Example: See the RNTester AppDelegate.mm.
JS
- Remove any references to
alertAction. - Remove the
handlerargument on any calls toremoveEventListener. - Replace any usages of
repeatIntervalby firing multiple notifications usingfireDateorfireIntervalSecondsinstead. - Note that
soundNamewill be null when it is accessed on aNotificationreturned fromgetScheduledLocalNotifications()andgetDeliveredNotifications().
Usunięcie wtyczki Flipper React Native
Korzystanie z Flippera do inspekcji układów React Native, żądań sieciowych i innych funkcji wtyczek React Native nie jest już wspierane. W wersji 0.74 usunęliśmy natywne biblioteki Flippera i kod konfiguracyjny z nowych projektów React Native. Oznacza to mniej zależności i szybszą lokalną konfigurację (zobacz oryginalny RFC).
Różnicę w usunięciu Flippera w twojej aplikacji można zobaczyć w Upgrade Helper. Jeśli chcesz zachować Flippera w istniejącej aplikacji, zignoruj odpowiednie linie różnic.
💡 To re-integrate Flipper
Flipper can still be used as a standalone tool for debugging an Android or iOS app, and can be manually integrated by following the Flipper docs (Android guide, iOS guide).
We recommend that teams invest in switching to native debugging tooling in Android Studio and Xcode.
Zastępowanie Flippera
Istnieje kilka dedykowanych narzędzi do debugowania, które zastępują funkcje Flippera. Więcej informacji znajdziesz w doskonałym artykule Jamona Holmgrena Dlaczego nie potrzebujesz Flippera w swojej aplikacji React Native.
Debugowanie JavaScript
Debugger Hermesa pozostaje naszą rekomendowaną opcją debugowania dla wersji 0.74. Możesz też wypróbować Eksperymentalny Nowy Debugger, który jest również domyślny w Expo. To nadal wczesna wersja preview — znane problemy i aktualizacje można śledzić tutaj.
Inne zmiany łamiące kompatybilność
Ogólne
- Właściwości
start/endw stylach zawsze odnoszą się teraz do kierunku pisania (#42251).
Android
-
Usunięto
JSIModule*zFabricUIManagerProvider(#42059).- To API nie było używane w open source — zamiast tego użyj TurboModules.
-
Oznaczono jako przestarzałe
UIManagerModule.showPopupMenuiUIManagerModule.dismissPopupMenu(#42441)- To API zostało przeniesione do pakietu npm
@react-native/popup-menu-androidi zostanie usunięte w wersji 0.75.
- To API zostało przeniesione do pakietu npm
iOS
-
Usunięto argumenty
configFilenameiconfigKeyz CLI generującego kod na iOS (#41533). -
Zmiana obsługi
bundleURL(#43994).- Wcześniej
bundleURLbył ustawiany przy starcie React Native jako zmienna instancji i nie można go było aktualizować. - Teraz
bundleUrljest funkcją, która jest ponownie wyliczana w razie potrzeby, umożliwiając użycie innego adresu URL przy odświeżaniach. - Ta zmiana wpłynie na twoją aplikację tylko wtedy, gdy modyfikowałeś zmienną
bundleURLpo uruchomieniu aplikacji. W takim przypadku przenieś logikę aktualizującą zmienną do funkcjibundleURLwAppDelegate.
- Wcześniej
Pełną listę zmian łamiących kompatybilność znajdziesz w pełnym dzienniku zmian.
Znane problemy
iOS
- Szczególny przypadek przy używaniu wielu okien: Gdy główne okno jest nieaktywne, a system próbuje wyświetlić okno dialogowe, dialog nie pojawia się w odpowiedniej pozycji na ekranie. Poprawka jest w trakcie implementacji w #44167 i zostanie wydana w wersji 0.74.1.
Podziękowania
React Native 0.74 zawiera ponad 1673 commity od 57 współtwórców. Dziękujemy za waszą ciężką pracę!
Dziękujemy wszystkim dodatkowym autorom, którzy pracowali nad dokumentowaniem funkcji w tym poście o wydaniu:
-
Nick Gerleman za Yoga 3.0
-
Joe Vilches za Yoga 3.0
-
Riccardo Cipolleschi za Nowa Architektura: Bridgeless domyślnie
-
Samuel Susla za Nowa Architektura: Zbatchowane aktualizacje
onLayout -
Tim Yung za Usunięcie przestarzałych
PropTypes -
Ingrid Wang za Zmiany API w PushNotificationIOS (przestarzałe)
Aktualizacja do wersji 0.74
Do sprawdzenia zmian kodu między wersjami React Native w istniejących projektach użyj React Native Upgrade Helper, dodatkowo do dokumentacji aktualizacji.
Aby utworzyć nowy projekt:
npx react-native@latest init MyProject
Jeśli używasz Expo, React Native 0.74 będzie obsługiwany w Expo SDK 51.
0.74 jest teraz najnowszą stabilną wersją React Native, a wersja 0.71.x przechodzi do nieobsługiwanych. Więcej informacji znajdziesz w polityce wsparcia React Native. Planujemy opublikować końcową aktualizację końca wsparcia dla wersji 0.71 na początku maja.




