跳至主要內容

React Native 0.77 - 全新造型功能、Android 16KB 頁面支援、Swift 範本

·15 分鐘閱讀
Vojtech Novak
Vojtech Novak
Expo 軟體工程師
Mazen Chami
Mazen Chami
InfiniteRed 軟體工程師
Blake Friedman
Blake Friedman
Meta 軟體工程師
Rob Hogan
Rob Hogan
Meta 軟體工程師

今天,我們很高興發布 React Native 0.77!

此版本推出多項功能:全新的造型功能,例如支援 display: contentsboxSizingmixBlendModeoutline 相關屬性,以提供更強大的版面配置選項;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

Container.jsx
function Container() {
return (
<View style={styles.container}>
<Widget />
</View>
);
}

display contents - setup

現在,讓我們建構一個新的 Alerting 包裝函式組件,目標是在按下其下方的組件時,使用實驗性指標事件來警示使用者。為了清楚起見,此組件的背景設為藍色。看起來可能像下面的組件

Container.jsx
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」方塊在點擊時發出警示。

before display contents

如果我們再次嘗試,同時在 AlertingView 包裝函式上設定 display: contents,我們只會在使用者在 Widget 的原始邊界內按下時看到警示。這是因為 Alerting 不再新增自己的方塊,但仍可觀察從 Widget 冒泡的指標事件。

Container.jsx
function Alerting({children}) {
return (
<View
style={{display: 'contents'}}
onPointerDown={() => alert('Hello World!')}>
{children}
</View>
);
}

// ... function Container ...

after display contents

方塊尺寸調整

boxSizing 屬性定義元素的各種尺寸調整屬性 (widthheightminWidthminHeight 等) 的計算方式。如果 boxSizingborder-box,則這些尺寸會套用至元素的邊框方塊。如果為 content-box,則它們會套用至元素的內容方塊。預設值為 border-box,這與 Web 上的預設值不同。Web 文件是很好的資訊來源,如果您想進一步了解此屬性的運作方式。

警告

border-box 一直以來都是預設值,而且在我們新增 content-box 之前一直是唯一的 boxSizing 值。變更預設值會是一個重大變更,可能會突然中斷多個版面配置。我們決定保留 border-box 作為預設值,以確保回溯相容性。

若要了解 border-boxcontent-box 之間的差異,請查看這些範例,其中兩個 View 都具有 padding: 20borderWidth: 10。使用 border-box 時,我們會考量邊框和邊距來調整尺寸;使用 content-box 時,我們只會考量內容來調整尺寸。

after display contents

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:建立具有來源色彩的明度以及背景幕色彩的色調和飽和度的色彩。這會產生與色彩模式相反的效果。

blend mode

外框屬性

我們也推出了 outlineWidthoutlineStyleoutlineSpreadoutlineColor。這些外框屬性的運作方式與各自的 border 屬性非常相似,但它是圍繞邊框方塊而非圍繞邊距方塊呈現。這些屬性允許透過繪製元素的外框來醒目提示元素,而不會影響其版面配置。

請查看MDN 文件以取得更多詳細資訊。

outline props

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-androidrun-ios 社群 CLI 命令。這些鍵盤快速鍵提供了較差的開發人員體驗,而且很少使用。此外,我們認為框架更適合協調終端機輸出。

您可以在這篇專文中閱讀有關此變更的更多資訊。

社群範本:Swift 作為 iOS 應用程式的程式設計語言

資訊

使用 Expo 的專案不應受到此變更的影響。

此變更讓我們可以透過將三個檔案 (main.mAppDelegate.hAppDelegate.mm) 替換為單一的新AppDelegate.swift,來縮減社群範本的大小。

這在技術上是一個重大變更:您會在升級協助程式中看到從 Objective-C 到 Swift 的變更,如下所示

Swift Upgrade Helper

您不必移轉至 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 行如下

AppDelegate.mm
#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 ToolsRadon 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
  • 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()

此外,已移除或限制多個 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 次提交。感謝您的辛勤工作!

感謝所有為此發布文章中記錄功能做出貢獻的其他作者

升級至 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 的最終終止生命週期更新。