React Native 0.78 - React 19 及更多
今天我們很高興發布 React Native 0.78!
此版本在 React Native 中推出 React 19,以及其他相關功能,例如 Android Vector 可繪製物件的原生支援,以及更佳的 iOS 棕地整合。
今天我們很高興發布 React Native 0.78!
此版本在 React Native 中推出 React 19,以及其他相關功能,例如 Android Vector 可繪製物件的原生支援,以及更佳的 iOS 棕地整合。
每年,React Native 社群的核心貢獻者都會與 React Native 團隊齊聚一堂,共同塑造此專案的方向。
去年也不例外,只有一個小小的例外。我們通常會在 React Universe Conf (前身為 React Native EU) 前一天,在弗羅茨瓦夫的 Callstack 總部會面。在 2024 年,我們從過去的經驗中學習,連續兩天舉辦峰會,以便我們有更多非結構化的時間在一起。
這項年度傳統已成為貢獻者分享見解和表達疑慮的寶貴機會,也讓核心團隊分享他們的計畫,並從 React Native 生態系統的主要貢獻者 (包括合作夥伴公司、個別程式庫作者和朋友) 收集意見回饋。
我們將峰會分為兩個主題,涵蓋以下主題
在此部落格文章中,我們想讓您先睹為快這次聚會的成果。
我們針對 React Native 的版本發布流程進行了廣泛的討論。核心團隊感謝 Meta 外部的貢獻者參與版本發布的價值,並強調擁有每晚發布版本的重要性,這對於樹狀結構外平台 (例如 React Native visionOS)、程式庫維護者 (Reanimated) 和框架 (Expo) 特別有益。我們討論了版本發布的頻率,有些人要求更頻繁的版本發布以更快地發布修復程式,而另一些人則對第三方程式庫的影響和升級工作表示擔憂。
我們還集思廣益,討論如何減少無意的重大變更,並改進關於 React Native 和第三方相依性之間相容性的溝通。
此會議顯示管理 React Native 的版本發布有多複雜,以及考慮到生態系統的所有不同部分,此主題有多敏感。
現在全新架構已穩定發布,我們討論了接下來應該關注什麼。下一個重大事件會是什麼?主題圍繞著
本次會議專門討論 Microsoft 關於將 Web API 子集引入 React Native 的 RFC。它旨在透過利用熟悉的 API 來增強 React Native 的可擴展性並吸引更多 Web 開發人員。開放存取大量現有的開放原始碼 Web 程式庫,這些程式庫沒有明確的 React Native 支援。
Web API 規格的標準化不僅對 React Native 的成長有利,而且至關重要,並且與我們的多平台願景和 react-strict-dom 專案非常吻合。Web 透過其規格提供統一的介面,而 React Native 社群模組目前缺乏這種介面。Microsoft 已識別出約 200 個基本 Web API,可以首先為他們支援的平台 (iOS、Android、Windows 和 macOS) 實作。
我們鼓勵程式庫開發人員盡可能使其 API 與 Web 規格對齊,因為這種標準化將提高跨平台的程式碼可攜性和開發人員體驗。
雖然該提案似乎對 React Native 的未來有利,但我們仍在集思廣益討論下一步。我們注意到的一個擔憂是 API 的治理,以及它們是否需要與平台實作分開儲存庫。另一個擔憂是,如果特定平台允許 W3C 未指定的行為,則會偏離官方規格。我們需要弄清楚如何避免捆綁不必要的模組,例如使用 Babel 外掛程式。更不用說這樣做的範圍非常大。
本次會議的結論強化了兩個關鍵點:首先,React Native 社群在盡可能採用 Web 相容規格方面存在強烈的共識。其次,我們需要為如何在不同平台上單獨維護這些 Web API 實作建立明確的技術策略。Microsoft 可以與 Callstack 合作,完善原始 RFC,並為少數 API 產生概念驗證實作,作為社群倡議。這種增量方法將有助於我們在擴大範圍之前驗證設計和開發人員體驗。
2019 年,React Native 團隊啟動了 Lean Core 倡議。目標是解決 React Native 核心的表面區域,並減少過時和舊版的 API 和組件。從那時起,React Native 組件和 API 表面就應該再次進行清理。
今天,有許多組件沒有積極維護,但有更佳的社群替代方案。此外,還有一些組件具有重複項,最終應加以整合以提高可維護性。
在 API 方面,許多 JS 層 API 都與原生 iOS 和 Android 實作相關聯,而不是真正與平台無關。例如,使用 Pressable,我們有 android_disableSound 和 android_ripple 等屬性。理想情況下,React Native 組件應具有最小的 API 表面,而該表面不與任何特定平台相關聯。
隨著樹狀結構外平台越來越普及並被生態系統更多地採用,需要有一條路徑來減少 React Native 核心的組件和 API 表面,減輕 React Native 核心團隊的負擔,並使樹狀結構外平台和程式庫維護者更容易保持最新狀態。
作為額外的好處,這將使初學者應用程式開發人員更容易上手 React Native,因為他們需要學習的重複組件和「陷阱」更少。如果存在更佳的社群替代方案,可以引導開發人員並鼓勵他們使用可用的社群替代方案。
在會議期間,我們討論了
下一步,核心貢獻者群組將研究收集更多遙測和資料、評估社群替代方案,並彙編一份詳細說明建議變更的 RFC。
最近,Marc Rousavy 推出了 Nitro 模組,作為建立原生模組的替代方法。Nitro 模組利用實驗性的 C++ Swift Interop,並整合了一系列增強功能,可以在某些情況下提高效能。但是,在本次會議期間,我們討論了 Nitro 模組和現有 TurboModules 之間涉及的各種權衡取捨。
雖然 Nitro 模組提供了一些效能優勢,但它們也存在需要解決的限制和考量。例如,使用實驗性互通功能可能會引入 TurboModules 中不存在的複雜性或相容性問題。我們的討論重點是這些權衡取捨,以及將 Nitro 模組的一些改進向上游整合到 React Native Core 中的可能性,這可以讓開發人員從更高效能的模組中受益。
樹狀結構外平台展現了 React Native 的全部威力,我們可以在行動裝置、桌面甚至 VR/XR 裝置上運行的不同平台之間共用一個 JS 程式碼庫。目前建立這樣的平台並不是最容易的過程,實際上沒有關於如何建立、開發和維護事物的指南。此外,React Native Core 在某種程度上與 Android 和 iOS 平台相關聯。未來,我們的目標可能是實現所有平台都受到平等對待,並透過相同的 API 與 C++/JS 核心整合的情境。
在本次會議期間,不同平台的維護者討論了問題是什麼、他們遇到的困難以及統一建立和維護新樹狀結構外平台的流程的解決方案應該是什麼。
本次會議的另一個方面是討論 CocoaPods 以及與管理原生相依性相關的未來計畫。最近,CocoaPods 團隊宣布他們已轉為維護模式,並且不會發布新的重大改進或功能。可以使用各種替代方案,在本次會議期間,我們討論了它們的優缺點,以及移轉的外觀。
來自 Microsoft 的 Steven 和 Saad (react-native-windows 和 react-native-macos 的維護者) 主持了一次會議,以聽取和收集與桌面平台相關的貢獻者的意見回饋。討論的主題包括探索如何提高 React Native 在桌面的採用率 (例如在 Visual Studio 中擁有專用工作流程,或將桌面公開為 Nx 的一部分),以及如何支援 Expo,這一直是提高採用率的持續痛點。
macOS 和 Windows 之間社群模組的可用性存在很大差異,這主要是因為 iOS 程式碼大多與 macOS 相容,而 RNW 需要客製化的實作。在為 Windows 版 React Native 開發全新架構時,團隊看到了 C++ 模組的潛力,它可以實現更多跨平台的程式碼共用,這有望減輕以桌面平台為目標的負擔。值得注意的是,在社群方面,Software Mansion 正在努力為他們最受歡迎的模組 (例如 React Native Screens、Gesture Handler 和 Reanimated) 新增桌面支援。
我們仍然對幾天共度幾個小時如何產生如此多的知識共享和想法交流印象深刻。在本次峰會期間,我們為有助於我們改進和重塑 React Native 生態系統的倡議播下了種子。
如果您有興趣加入 React Native 的開發,請務必加入我們的開放倡議並閱讀我們網站上的 貢獻指南。我們希望在未來也能與您親自見面!
今天我們很高興發布 React Native 0.77!
此版本發布了多項功能:全新的樣式功能,例如支援 display: contents
、boxSizing
、mixBlendMode
和 outline
相關屬性,以提供更強大的版面配置選項;Android 16KB 頁面支援,與較新的 Android 裝置相容。我們也正在透過將社群範本移轉到 Swift 來實現現代化,同時繼續支援和維護與喜歡 Objective-C 的開發人員的相容性。
既然 0.71 已推出,我們想分享一些關於事件的關鍵資訊,該事件在 2022 年 11 月 4 日發布 React Native 和 Expo Android 建置的第一個 0.71 版本候選版時,中斷了所有 React Native 版本的 Android 建置。
最近,協助處理該事件的貢獻者參加了一次事後檢討會議,以詳細討論發生了什麼事、我們從中學到了什麼,以及我們將採取哪些行動來避免未來發生類似的中斷事件。
隨著 0.71 的發布,React Native 正在透過以下變更投資 TypeScript 體驗
在這篇文章中,我們將涵蓋這些變更對您作為 TypeScript 或 Flow 使用者意味著什麼。
大家好!
隨著新的行動作業系統版本將在今年稍後發布,我們建議您事先準備好 React Native 應用程式,以避免在這些版本普遍可用時發生回歸。
長期以來,Apple 一直不鼓勵使用 UIWebView,轉而支持 WKWebView。在即將在未來幾個月內發布的 iOS 12 中,UIWebView 將被正式棄用。React Native 的 iOS WebView 實作嚴重依賴 UIWebView 類別。因此,鑑於這些發展,我們為 WebView React Native 組件建置了一個使用 WKWebView 的全新原生 iOS 後端。
這些變更的尾聲已在 此提交 中完成,並將在 0.57 版本中提供。
若要選擇加入此新實作,請使用 useWebKit
屬性
<WebView
useWebKit={true}
source={{url: 'https://www.google.com'}}
/>
UIWebView
沒有合法的方式來促進在 WebView 中運行的 JavaScript 與 React Native 之間的通訊。當訊息從 WebView 發送時,我們依賴一種駭客技術將它們傳遞到 React Native。簡而言之,我們將訊息資料編碼為具有特殊架構的 URL,並將 WebView 導航到該 URL。在原生端,我們攔截並取消此導航,從 URL 解析資料,最後呼叫到 React Native。此實作容易出錯且不安全。我很高興地宣布,我們已利用 WKWebView
功能完全取代它。
WKWebView 相較於 UIWebView 的其他優點包括更快的 JavaScript 執行速度和多進程架構。請參閱此 2014 年 WWDC 以了解更多詳細資訊。
如果您的組件使用以下屬性,則在切換到 WKWebView 時可能會遇到問題。目前,我們建議您避免使用這些屬性
行為不一致
automaticallyAdjustContentInsets
和 contentInsets
(提交)
當您將 contentInsets 新增到 WKWebView
時,它不會變更 WKWebView
的檢視區。檢視區大小與框架大小相同。使用 UIWebView
時,檢視區大小實際上會變更 (如果內容內邊距為正數,則會變小)。
backgroundColor
(提交)
使用 WebView 的新 iOS 實作時,如果您使用此屬性,則背景顏色可能會閃爍到檢視中。此外,WKWebView
轉譯透明背景的方式與 UIWebview
不同。請查看提交說明以了解更多詳細資訊。
不支援
scalesPageToFit
(提交)
WKWebView 不支援 scalesPageToFit 屬性,因此我們無法在 WebView React Native 組件上實作此屬性。
隨著技術的進步和行動應用程式對日常生活變得越來越重要,建立無障礙應用程式的必要性也日益重要。
React Native 有限的無障礙功能 API 一直是開發人員的一大痛點,因此我們對無障礙功能 API 進行了一些更新,以使其更容易建立包容性行動應用程式。
accessibilityComponentType
和 accessibilityTraits
是兩個屬性,用於告訴 Android 上的 TalkBack 和 iOS 上的 VoiceOver 使用者正在與哪種 UI 元素互動。這些屬性的兩個最大問題是
accessibilityTraits
允許 17 個不同的值,而 Android 上的 accessibilityComponentType
僅允許 4 個值。此外,這些值在很大程度上沒有重疊。即使這兩個屬性的輸入類型也不同。accessibilityTraits
允許傳入特徵陣列或單個特徵,而 accessibilityComponentType
僅允許單個值。無障礙功能提示可協助使用 TalkBack 或 VoiceOver 的使用者了解當他們對無障礙功能元素執行操作時會發生什麼情況,而這些情況僅憑無障礙功能標籤並不明顯。這些提示可以在設定面板中開啟和關閉。先前,React Native 的 API 完全不支援無障礙功能提示。
一些視力障礙使用者在其行動電話上使用反轉色彩,以獲得更高的螢幕對比度。Apple 為 iOS 提供了一個 API,允許開發人員忽略某些檢視。這樣,當使用者開啟反轉色彩設定時,影像和影片就不會失真。React Native 目前不支援此 API。
為了消除 accessibilityComponentType
和 accessibilityTraits
之間的混淆,我們決定將它們合併為單個屬性。這是合理的,因為它們在技術上具有相同的預期功能,並且透過合併它們,開發人員在建置無障礙功能時不再需要擔心特定於平台的複雜性。
背景
在 iOS 上,UIAccessibilityTraits
是一個可以設定在任何 NSObject 上的屬性。透過 javascript 屬性傳遞到原生的 17 個特徵中的每一個都對應於 Objective-C 中的 UIAccessibilityTraits
元素。特徵各自由一個長整數表示,並且每個設定的特徵都進行 OR 運算。
然而,在 Android 上,AccessibilityComponentType
是 React Native 創造的一個概念,並且不直接對應於 Android 中的任何屬性。無障礙功能由無障礙功能委派處理。每個檢視都有一個預設的無障礙功能委派。如果您想要自訂任何無障礙功能操作,則必須建立新的無障礙功能委派,覆寫您想要自訂的特定方法,然後將您正在處理的檢視的無障礙功能委派設定為與新的委派相關聯。當開發人員設定 AccessibilityComponentType
時,原生程式碼會根據傳入的組件建立新的委派,並將檢視設定為具有該無障礙功能委派。
已做的變更
對於我們的新屬性,我們想要建立兩個屬性的超集。我們決定使新屬性主要以現有屬性 accessibilityTraits
為模型,因為 accessibilityTraits
具有顯著更多的值。這些特徵的 Android 功能將透過修改無障礙功能委派來進行 Polyfill。
accessibilityTraits
在 iOS 上可以設定為 17 個 UIAccessibilityTraits 值。但是,我們並未將它們全部包含為我們新屬性的可能值。這是因為設定其中某些特徵的效果實際上並不是很清楚,並且這些值中的許多值實際上從未使用過。
UIAccessibilityTraits 值通常設定為兩種用途之一。它們要么描述 UI 元素具有的角色,要么描述 UI 元素所處的狀態。我們觀察到先前屬性的大多數用法通常使用一個代表角色的值,並將其與「狀態已選取」、「狀態已停用」或兩者結合使用。因此,我們決定建立兩個新的無障礙功能屬性:accessibilityRole
和 accessibilityState
。
accessibilityRole
新屬性 accessibilityRole
用於告訴 Talkback 或 Voiceover UI 元素的角色。此新屬性可以採用以下值之一
無
按鈕
連結
搜尋
影像
鍵盤按鍵
文字
可調整
標題
摘要
影像按鈕
此屬性僅允許傳入一個值,因為 UI 元素通常在邏輯上不會採用其中多個值。例外情況是影像和按鈕,因此我們新增了一個角色 imagebutton,它是兩者的組合。
accessibilityStates
新屬性 accessibilityStates
用於告訴 Talkback 或 Voiceover UI 元素所處的狀態。此屬性採用一個陣列,其中包含以下值中的一個或兩個
已選取
已停用
為此,我們新增了一個新屬性 accessibilityHint
。設定此屬性將允許 Talkback 或 Voiceover 向使用者朗讀提示。
accessibilityHint
此屬性採用字串形式的無障礙功能提示以供朗讀。
在 iOS 上,設定此屬性將會在 view 上設定對應的原生屬性 AccessibilityHint。如果 iPhone 上已開啟「輔助使用提示」,Voiceover 便會讀取此提示。
在 Android 上,設定此屬性會將提示的值附加到輔助使用標籤的末尾。此實作的優點是它模仿了 iOS 上提示的行為,但此實作的缺點是這些提示無法像在 iOS 上那樣在 Android 的設定中關閉。
我們在 Android 上做出此決定的原因是,通常輔助使用提示會對應於特定動作(例如,點擊),而我們希望在各個平台之間保持行為一致。
accessibilityIgnoresInvertColors
我們將 Apple 的 API AccessibilityIgnoresInvertColors 公開給 JavaScript,因此現在當您有一個不希望顏色被反轉的 view(例如,圖片)時,您可以將此屬性設定為 true,這樣它就不會被反轉。
這些新屬性將在 React Native 0.57 版本中提供。
如果您目前正在使用 accessibilityComponentType
和 accessibilityTraits
,以下是您可以升級到新屬性的步驟。
最簡單的使用案例可以使用執行 jscodeshift 腳本來替換。
此腳本替換了以下實例
accessibilityTraits=“trait”
accessibilityTraits={[“trait”]}
替換為
accessibilityRole= “trait”
此腳本還會移除 AccessibilityComponentType
的實例(假設您在設定 AccessibilityComponentType
的任何地方,也會設定 AccessibilityTraits
)。
對於使用 AccessibilityTraits
但沒有對應的 AccessibilityRole
值,以及將多個 traits 傳遞到 AccessibilityTraits
的情況,則必須進行手動程式碼修改 (codemod)。
一般而言,
accessibilityTraits= {[“button”, “selected”]}
將會手動替換為
accessibilityRole=“button”
accessibilityStates={[“selected”]}
這些屬性已經在 Facebook 的程式碼庫中使用。Facebook 的程式碼修改 (codemod) 非常簡單。jscodeshift 腳本修復了我們約一半的實例,另一半是手動修復的。總體而言,整個過程花費不到幾個小時。
希望您會覺得更新後的 API 很有用!並請繼續讓應用程式更易於存取!#inclusion
距離我們上次發布關於 React Native 的狀態更新已經有一段時間了。
在 Facebook,我們比以往任何時候都更常使用 React Native,並將其用於許多重要的專案。我們最受歡迎的產品之一是 Marketplace,它是我們應用程式中的頂級標籤之一,每月有 8 億人使用。自 2015 年創建以來,Marketplace 的所有內容都是使用 React Native 建構的,包括應用程式不同部分的一百多個全螢幕視圖。
我們也將 React Native 用於應用程式的許多新部分。如果您觀看了上個月的 F8 主題演講,您會認出「血液捐贈」、「危機應對」、「隱私捷徑」和「健康檢查」——所有這些都是最近使用 React Native 建構的功能。Facebook 主應用程式以外的專案也在使用 React Native。新的 Oculus Go VR 頭戴裝置包含配套行動應用程式,該應用程式完全使用 React Native 建構,更不用說 React VR 為頭戴裝置本身的許多體驗提供動力。
當然,我們也使用許多其他技術來建構我們的應用程式。Litho 和 ComponentKit 是我們在應用程式中廣泛使用的兩個函式庫;兩者都提供類似 React 的元件 API,用於建構原生畫面。React Native 從未打算取代所有其他技術——我們專注於使 React Native 本身變得更好,但我們很高興看到其他團隊借鑒 React Native 的想法,例如將即時重新載入也帶到非 JavaScript 程式碼。
當我們在 2013 年啟動 React Native 專案時,我們將其設計為在 JavaScript 和原生之間具有單一「橋樑」,該橋樑是非同步、可序列化且批次處理的。正如 React DOM 將 React 狀態更新轉換為對 DOM API(如 document.createElement(attrs)
和 .appendChild()
)的命令式、變異呼叫一樣,React Native 被設計為傳回單一 JSON 訊息,其中列出了要執行的變異,例如 [["createView", attrs], ["manageChildren", ...]]
。我們將整個系統設計為永遠不依賴於取得同步回應,並確保該清單中的所有內容都可以完全序列化為 JSON 並返回。我們這樣做是為了它給予我們的靈活性:在此架構之上,我們能夠建構諸如 Chrome 除錯 之類的工具,這些工具透過 WebSocket 連線非同步執行所有 JavaScript 程式碼。
在過去 5 年中,我們發現這些初始原則使得建構某些功能變得更加困難。非同步橋樑意味著您無法將 JavaScript 邏輯與許多期望同步回應的原生 API 直接整合。批次處理的橋樑會將原生呼叫排隊,這意味著讓 React Native 應用程式呼叫以原生方式實作的函式更加困難。可序列化的橋樑意味著不必要的複製,而不是在兩個世界之間直接共享記憶體。對於完全在 React Native 中建構的應用程式,這些限制通常是可以忍受的。但對於在 React Native 和現有應用程式程式碼之間具有複雜整合的應用程式,它們令人沮喪。
我們正在進行 React Native 的大規模重新架構,以使該框架更靈活,並在混合 JavaScript/原生應用程式中更好地與原生基礎架構整合。 透過此專案,我們將應用我們在過去 5 年中學到的知識,並逐步將我們的架構帶向更現代化的架構。我們正在重寫 React Native 的許多內部組件,但大多數變更都在幕後:現有的 React Native 應用程式將繼續運作,幾乎沒有或沒有任何變更。
為了使 React Native 更輕量級並更好地適應現有的原生應用程式,此重新架構有三個主要的內部變更。首先,我們正在變更執行緒模型。UI 的每次更新不再需要執行三個不同執行緒上的工作,而是可以在任何執行緒上同步呼叫 JavaScript 以進行高優先順序的更新,同時仍將低優先順序的工作放在主執行緒之外以保持回應能力。其次,我們正在將非同步渲染功能整合到 React Native 中,以允許多個渲染優先順序並簡化非同步資料處理。最後,我們正在簡化我們的橋樑,使其更快更輕量級;原生和 JavaScript 之間的直接呼叫效率更高,並且將更容易建構跨語言堆疊追蹤等除錯工具。
一旦這些變更完成,更緊密的整合將成為可能。如今,如果不進行複雜的 hacks,就無法整合原生導航和手勢處理或原生元件(如 UICollectionView 和 RecyclerView)。在我們變更執行緒模型之後,建構此類功能將會很簡單。
隨著這項工作接近完成,我們將在今年稍後發布有關此工作的更多詳細資訊。
除了 Facebook 內部的社群之外,我們很高興在 Facebook 外部擁有蓬勃發展的 React Native 使用者和協作者群體。我們希望更多地支持 React Native 社群,既能更好地服務 React Native 使用者,又能使該專案更容易貢獻。
正如我們的架構變更將有助於 React Native 與其他原生基礎架構更乾淨地互操作一樣,React Native 在 JavaScript 方面也應該更精簡,以更好地適應 JavaScript 生態系統,其中包括使 VM 和 bundler 可交換。我們知道重大變更的步調可能難以跟上,因此我們希望找到減少主要版本發布次數的方法。最後,我們知道有些團隊正在尋找更全面的文件,例如啟動最佳化等主題,而我們在這方面的專業知識尚未寫下來。預計在未來一年中會看到其中一些變更。
如果您正在使用 React Native,您就是我們社群的一份子;請繼續告訴我們如何才能讓 React Native 對您更好。
React Native 只是行動開發人員工具箱中的一種工具,但我們堅信它——而且我們每天都在使其變得更好,在過去一年中,有來自 500 多位貢獻者的 2500 多次提交。