React Native 0.77 - 全新造型功能、Android 16KB 頁面支援、Swift 範本
今天,我們很高興發布 React Native 0.77!
此版本推出多項功能:全新的造型功能,例如支援 display: contents
、boxSizing
、mixBlendMode
和 outline
相關屬性,以提供更強大的版面配置選項;Android 16KB 頁面支援,以與較新的 Android 裝置相容。我們也正在透過將社群範本移轉至 Swift 來使其現代化,同時繼續支援和維護與偏好 Objective-C 的開發人員的相容性。
重點
重大變更
重點
全新的 CSS 功能,可改善版面配置、尺寸調整和混合
React Native 0.77 進一步實現了我們讓 React Native 與 Web 對齊的目標。我們新增了對全新 CSS 屬性的支援,讓您更能掌控應用程式的版面配置、尺寸調整和混合。這些變更可以協助簡化複雜的版面配置、新增紋理,並讓您的應用程式更易於存取。
所有這些新功能僅適用於全新架構。
使用 display: contents
簡化版面配置
display: contents
屬性允許元素從版面配置結構中消失,同時其子元素仍會呈現,如同它們是父元素的直接子元素一樣。這對於想要將樣式套用至子元素而不影響版面配置、建構必須處理事件的包裝函式組件,或需要與 ShadowTree 互動的造型目的非常有用。
從技術上來說,display: contents
會呈現元素而不產生版面配置方塊,但會保留元素的子元素的版面配置方塊。具有 display: contents
的元素會有效地從檢視階層中扁平化。
讓我們看看這個範例,我們想要在按下小工具時顯示警示。我們在容器檢視中放置了一個紅色 Widget
function Container() {
return (
<View style={styles.container}>
<Widget />
</View>
);
}
現在,讓我們建構一個新的 Alerting
包裝函式組件,目標是在按下其下方的組件時,使用實驗性指標事件來警示使用者。為了清楚起見,此組件的背景設為藍色。看起來可能像下面的組件
function Alerting({children}) {
return (
<View
style={{backgroundColor: 'blue'}}
onPointerDown={() => alert('Hello World!')}>
{children}
</View>
}
function Container() {
return (
<View style={styles.container}>
<Alerting>
<Widget />
</Alerting>
</View>
);
}
這並未完全達到我們想要的效果。Alerting
新增了一個新的版面配置方塊,具有自己的邊界,與子元素 Widget
分開。根據其包裝元素的樣式,這可能會導致顯著的視覺和功能變更。在此範例中,藍色背景會回應點擊發出警示,但我們希望只有紅色「Hello World」方塊在點擊時發出警示。
如果我們再次嘗試,同時在 Alerting
的 View
包裝函式上設定 display: contents
,我們只會在使用者在 Widget
的原始邊界內按下時看到警示。這是因為 Alerting
不再新增自己的方塊,但仍可觀察從 Widget
冒泡的指標事件。
function Alerting({children}) {
return (
<View
style={{display: 'contents'}}
onPointerDown={() => alert('Hello World!')}>
{children}
</View>
);
}
// ... function Container ...
方塊尺寸調整
boxSizing
屬性定義元素的各種尺寸調整屬性 (width
、height
、minWidth
、minHeight
等) 的計算方式。如果 boxSizing
為 border-box
,則這些尺寸會套用至元素的邊框方塊。如果為 content-box
,則它們會套用至元素的內容方塊。預設值為 border-box
,這與 Web 上的預設值不同。Web 文件是很好的資訊來源,如果您想進一步了解此屬性的運作方式。
border-box
一直以來都是預設值,而且在我們新增 content-box
之前一直是唯一的 boxSizing
值。變更預設值會是一個重大變更,可能會突然中斷多個版面配置。我們決定保留 border-box
作為預設值,以確保回溯相容性。
若要了解 border-box
和 content-box
之間的差異,請查看這些範例,其中兩個 View
都具有 padding: 20
和 borderWidth: 10
。使用 border-box
時,我們會考量邊框和邊距來調整尺寸;使用 content-box
時,我們只會考量內容來調整尺寸。
CSS mixBlendMode
mixBlendMode
屬性可讓您控制元素如何將其色彩與其堆疊內容中的其他元素混合。請查看MDN 文件,以取得每個混合功能的完整概觀。
為了協助更精細地控制混合在一起的內容,我們也新增了 isolation
屬性。在 View
上設定 isolation: isolate
會強制其形成堆疊內容。因此,您可以在某些上層 View
上設定此屬性,以確保具有 mixBlendMode
的某些後代 View
不會混合超出隔離的 View
。
mixBlendMode 值
normal
:元素繪製在其背景之上,而不進行混合。multiply
:來源色彩與目的地色彩相乘,並取代目的地。screen
:將背景幕和來源色彩值的補色相乘,然後對結果進行補色。overlay
:根據背景幕色彩值,將色彩相乘或螢幕化。darken
:選取背景幕和來源色彩中較暗的色彩。lighten
:選取背景幕和來源色彩中較亮的色彩。
color-dodge
:使背景幕色彩變亮以反映來源色彩。使用黑色繪製不會產生任何變更。
color-burn
:使背景幕色彩變暗以反映來源色彩。使用白色繪製不會產生變更。hard-light
:根據來源色彩值,將色彩相乘或螢幕化。效果類似於在背景幕上照射強烈的聚光燈。soft-light
:根據來源色彩值,使色彩變暗或變亮。效果類似於在背景幕上照射漫射的聚光燈。difference
:從較亮的色彩中減去兩種組成色彩中較暗的色彩。exclusion
:產生的效果類似於差異模式,但對比度較低。hue
:建立具有來源色彩的色調以及背景幕色彩的飽和度和明度的色彩。saturation
:建立具有來源色彩的飽和度以及背景幕色彩的色調和明度的色彩。color
:建立具有來源色彩的色調和飽和度以及背景幕色彩的明度的色彩。這會保留背景幕的灰階,並且適用於為單色影像著色或為彩色影像著色。luminosity
:建立具有來源色彩的明度以及背景幕色彩的色調和飽和度的色彩。這會產生與色彩模式相反的效果。
外框屬性
我們也推出了 outlineWidth
、outlineStyle
、outlineSpread
和 outlineColor
。這些外框屬性的運作方式與各自的 border
屬性非常相似,但它是圍繞邊框方塊而非圍繞邊距方塊呈現。這些屬性允許透過繪製元素的外框來醒目提示元素,而不會影響其版面配置。
請查看MDN 文件以取得更多詳細資訊。
Android 版本 15 支援與 16KB 頁面支援
在 Android 15 上強制邊緣到邊緣
我們已在先前的版本中完成一些工作,以支援 Android 15。Android 15 中最顯著的變更之一是當您使用 targetSdk
35 建構應用程式時,強制邊緣到邊緣顯示。
如果您尚未研究過此問題,請參閱我們先前的建議,了解應如何處理此問題,因為忽略此問題可能會破壞應用程式中的 UI。
如果您在應用程式中使用react-native-safe-area-context
,則該程式庫已為您處理強制邊緣到邊緣。
Android 的 16 KB 頁面大小支援
Android 15 推出對 16KB 記憶體頁面大小的支援,可為應用程式帶來效能改善等優點,但可能會使先前基於 4KB 的應用程式在未來的裝置上不相容;目前,開發人員可以選擇加入功能,以便在選定的裝置上進行測試,為 16 KB 頁面大小成為作業系統預設值做好準備。
透過 0.77 版本,React Native 已準備好完全支援 16 KB 頁面大小,開發人員將能夠使用它來測試和發布適用於 16 KB 裝置的應用程式。
請參閱官方 Android 開發人員網站,以取得有關 16 KB 支援的更多資訊。
社群 CLI 和範本更新
社群 CLI:react-native init 淘汰
此版本完全完成了 React Native 0.75 中推出的 react-native init
命令的淘汰。
提醒您,您將無法再使用 react-native init
命令,但您必須
- 使用框架,例如 Expo,其具有自己的專用命令來建立新專案:
npx create-expo-app
- 使用
npx @react-native-community/cli init
直接叫用社群 CLI
社群 CLI:從 Metro 移除「在 iOS/Android 上執行」金鑰處理常式
在此版本中,我們從 Metro 中移除了「a」和「i」鍵盤快速鍵。這些快速鍵用於叫用 run-android
和 run-ios
社群 CLI 命令。這些鍵盤快速鍵提供了較差的開發人員體驗,而且很少使用。此外,我們認為框架更適合協調終端機輸出。
您可以在這篇專文中閱讀有關此變更的更多資訊。
社群範本:Swift 作為 iOS 應用程式的程式設計語言
使用 Expo 的專案不應受到此變更的影響。
此變更讓我們可以透過將三個檔案 (main.m
、AppDelegate.h
和 AppDelegate.mm
) 替換為單一的新AppDelegate.swift
,來縮減社群範本的大小。
這在技術上是一個重大變更:您會在升級協助程式中看到從 Objective-C 到 Swift 的變更,如下所示
您不必移轉至 Swift:iOS 社群範本的 Objective-C++ 變體仍然受到支援 (請注意,您仍然需要整合RCTAppDependencyProvider
)。雖然您可以隨時移轉回 Objective-C (如果您需要),但新專案將會使用 Swift 作為 iOS 應用程式語言產生。
限制
如果您的應用程式有一些以 C++ 撰寫的本機模組,您將無法在 Swift 中註冊它們,如本指南所示。
如果您的應用程式屬於此類別,請略過 AppDelegate 到 Swift 的移轉,並繼續為您的應用程式使用 Objective-C++。
React Native 核心主要使用 C++ 開發,以鼓勵 iOS 和 Android 以及其他平台之間的程式碼共用。Swift 和 C++ 之間的互通性尚未成熟或穩定。我們正在研究填補此差距並讓您也移轉至 Swift 的方法。
RCTAppDependencyProvider
React Native 0.77 稍微變更了應用程式載入協力廠商相依性的方式。這是社群範本中的新行,如果遺漏,可能會導致一些執行階段問題。請務必將其新增至您的應用程式。
對等的 Objective-C 行如下
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <ReactAppDependencyProvider/RCTAppDependencyProvider.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.moduleName = @"<Your app Name>";
self.dependencyProvider = [RCTAppDependencyProvider new];
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
// remaining of the AppDelegate
重大變更
移除 Metro 中的 console.log()
串流
我們希望 React Native 偵錯的每個方面都能可靠地運作,並符合現代瀏覽器工具的功能。為了達到此品質標準,透過 Metro 進行記錄轉送 (最初在 0.76 中已淘汰) 已在 0.77 中移除。
此整合依賴自訂方法與裝置上的偵錯目標進行通訊。透過此變更,我們正完全轉向 Chrome DevTools Protocol (CDP)。
- 若要檢視 JS 記錄,請使用React Native DevTools及其功能完整的「主控台」面板 — 支援記錄篩選、豐富的物件檢查、「即時表達式」及更多功能。
- 您也可以透過協力廠商擴充功能 (例如Expo Tools和Radon IDE) 將 VS Code 連線為 CDP 偵錯工具。
- 請注意,這些整合並非由 React 團隊直接支援。但是,我們正在努力在 2025 年提供第一方 VS Code 支援。
- Expo 繼續在 Expo CLI 中提供記錄串流。
如需更多資訊,請參閱JavaScript 記錄為何離開 Metro?
其他重大變更
一般
- 動畫
- 原生迴圈動畫不會在每次迴圈結束時傳送 React 狀態更新。
- 版面配置
- 現在將考量
ScrollView
上黏性標頭的position
。 - 絕對定位現在以更符合規範的方式運作
- 現在將考量
- JS 模組
- 移除
ReactFabricInternals
模組- 這將不再可存取
- 移除
- 原生模組
- 現在可以使用
NativeModules
物件在 JS 中載入 turbomodules。- 這改善了原生模組和 Turbo 原生模組之間的相容性
- 現在可以使用
- 套件
- dev-middleware:框架應指定相對於中介軟體主機的
serverBaseUrl
- dev-middleware:框架應指定相對於中介軟體主機的
- API 變更
- 從
AppRegistry
移除useConcurrentRoot
的類型,因為它已被忽略 - 從
NativeMethods
TypeScript 定義中移除refs
屬性。
- 從
- UX 變更
- 從開發伺服器金鑰命令中移除「在 iOS 上執行」和「在 Android 上執行」
Android
- Kotlin
- 這是 React Native 的第一個版本,其針對 Kotlin 2.0.21 建構。您可以在語言版本資訊中閱讀有關 Kotlin 2.0 的變更的更多資訊。
- API 變更
- 可為 Null 性
ReadableArray
中的非原始 Getter 現在已正確輸入為選用- 讓
ReactHost.createSurface()
方法不可為 Null
- 已重新命名
DevSupportManagerBase.getCurrentContext()
為DevSupportManagerBase.getCurrentReactContext()
- 可為 Null 性
此外,已移除或限制多個 API 的可見性,因此它們不再可存取。這些 API 是內部 API,React Native 開發人員不需要直接使用。您可以在下方找到完整清單
已移除的 Android API 清單
以下套件現在是內部套件,且不再可存取
com.facebook.react.views.progressbar
com.facebook.react.views.safeareaview
com.facebook.react.modules.accessibilityinfo
com.facebook.react.modules.appstate
com.facebook.react.modules.clipboard
com.facebook.react.modules.devmodule
com.facebook.react.modules.reactdevtoolssettings
com.facebook.react.views.unimplementedview
以下類別現在是內部類別或已移除,因此不再可存取
BackHandler.removeEventListener
BaseViewManagerInterface
BindingImpl
CompositeReactPackage
DebugOverlayTags
DefaultDevSupportManagerFactory
中的方法create()
DevToolsReactPerfLogger
FabricComponents
ImageStoreManager
InteropModuleRegistry
NativeModulePerfLogger
NoopPrinter
NotThreadSafeViewHierarchyUpdateDebugListener
OkHttpCallUtil
PrinterHolder
Printer
ReactDebugOverlayTags
ReactNativeFlipper
ReactViewBackgroundManager
ReactViewGroup.getBackgroundColor()
ReactVirtualTextShadowNode
ReactVirtualTextViewManager
SimpleSettableFuture
SwipeRefreshLayoutManager
TaskCompletionSource
- DefaultReactHost.getDefaultReactHost() 中的參數
jsBundleLoader
iOS
- API 變更
- 已移除
RCTConstants.RCTGetMemoryPressureUnloadLevel
partialBatchDidFlush
RCTRuntimeExecutor
UseNativeViewConfigsInBridgelessMode
- 由適當的功能旗標取代
UseTurboModuleInteropForAllTurboModules
- TM 的互通層始終開啟
- 已變更
- 將
CGColorRef
的使用替換為UIColor
- 將
- 已移除
RCTAppDelegate
現在需要使用RCTDependencyProvider
來載入協力廠商相依性- CocoaPods 為所有協力廠商相依性設定 C++ 版本,以避免編譯問題。
React 19?
React 19 已於 2024 年 12 月 6 日發布。當時,我們已經為 React Native 0.77 切割分支,而且我們已經發布了三個 React Native 0.77 的 RC。在 React Native 0.77 的發布中引入 React 19 為時已晚。
React 19 將在 React Native 0.78 中發布,而且我們已經為此版本切割分支。您可以透過使用以下命令建立新的應用程式來嘗試它
npx @react-native-community/cli init YourReact19App --version 0.78.0-rc.0
致謝
React Native 0.77 包含來自 161 位貢獻者的超過 1061 次提交。感謝您的辛勤工作!
感謝所有為此發布文章中記錄功能做出貢獻的其他作者
- Jakub Piasecki 為
display: contents
功能做出貢獻 - Nick Gerleman、Joe Vilches 和 Jorge Cabiedes Acosta 發布了全新的造型功能
- Alan Lee 提供 Android 16Kb 頁面支援內容
- Riccardo Cipolleschi 和 Oskar Kwaśniewski 支援將範本移轉至 Swift
- Nicola Corti 提供
react-native init
淘汰週期內容 - Alex Hunt 提供有關從 metro 移除
console.log
的內容
升級至 0.77
除了升級文件之外,請使用React Native 升級協助程式,以檢視現有專案的 React Native 版本之間的程式碼變更。
若要建立新專案
npx @react-native-community/cli@latest init MyProject --version latest
如果您使用 Expo,Expo SDK 52 將支援 React Native 0.77 (有關如何在您的 Expo 專案內將 React Native 更新至 0.77.0 的指示將在不久的將來在另一篇 Expo 部落格文章中提供)。
0.77 現在是 React Native 的最新穩定版本,而 0.74.x 已移至不受支援。如需更多資訊,請參閱React Native 的支援政策。我們的目標是在不久的將來發布 0.74 的最終終止生命週期更新。