上週我有機會參加在 Zynga 舊金山辦公室舉辦的 React Native Meetup。約有 200 人參加,這是一個與我附近對 React Native 感興趣的其他開發人員交流的好地方。

我特別有興趣了解更多關於 Zynga、Netflix 和 Airbnb 等公司如何使用 React 和 React Native。當晚的議程如下:
- React 中的快速原型設計
- 為 React Native 設計 API
- 彌合差距:在現有程式碼庫中使用 React Native
但首先,活動以簡短的介紹和近期新聞的簡要回顧開始
- 您知道 React Native 現在是 GitHub 上頂級的 JavaScript 儲存庫嗎?
- rnpm 現在是 React Native 核心的一部分!您現在可以使用
react-native link
代替 rnpm link
來 安裝具有原生依賴項的函式庫。
- React Native Meetup 社群正在快速成長!現在全球各地有超過 4,800 名開發人員參與各種 React Native meetup 群組。
如果其中一個 meetup 在您附近舉行,我強烈建議您參加!
Zynga 的 React 快速原型設計
第一輪新聞之後是 Zynga 的簡短介紹,他們是當晚的主辦方。Abhishek Chadha 談到了他們如何使用 React 在行動裝置上快速原型設計新的體驗,並示範了一個類似 Draw Something 的應用程式的快速原型。他們使用了類似 React Native 的方法,透過橋接器提供對原生 API 的存取。當 Abhishek 使用裝置的相機拍攝觀眾的照片,然後在某人的頭上畫了一頂帽子時,就示範了這一點。
Netflix 的 React Native API 設計
接下來是當晚的第一場主題演講。Netflix 的資深軟體工程師 Clarence Leung 介紹了他關於「為 React Native 設計 API」的演講。首先,他指出人們可能會開發的兩種主要函式庫類型:元件(例如標籤列和日期選擇器)和提供對原生服務(例如相機膠卷或應用程式內付款)存取的函式庫。在為 React Native 建構函式庫時,可以採用兩種方法
- 提供平台特定的元件
- 一個跨平台函式庫,為 Android 和 iOS 提供類似的 API
每種方法都有其自身的考量,這取決於您來決定哪種方法最適合您的需求。
方法 #1
作為平台特定元件的一個範例,Clarence 談到了核心 React Native 中的 DatePickerIOS 和 DatePickerAndroid。在 iOS 上,日期選擇器作為 UI 的一部分呈現,可以輕鬆嵌入現有視圖中,而 Android 上的日期選擇器則以模態方式呈現。在這種情況下,提供單獨的元件是有意義的。
方法 #2
另一方面,照片選擇器在 Android 和 iOS 上的處理方式類似。有一些細微的差異 — 例如,Android 不像 iOS 那樣將照片分組到「自拍」等資料夾中 — 但這些差異可以輕鬆地使用 if
語句和 Platform
元件來處理。
無論您選擇哪種方法,最好盡可能縮小 API 介面並建構應用程式特定的函式庫。例如,iOS 的應用程式內購買框架支援一次性、消耗性購買以及可續訂的訂閱。如果您的應用程式只需要支援消耗性購買,您可以放棄在您的跨平台函式庫中對訂閱的支援。

在 Clarence 的演講結束時,有一個簡短的問答環節。其中一個有趣的資訊是,Netflix 為這些函式庫編寫的 React Native 程式碼中,約有 80% 是在 Android 和 iOS 之間共享的。
彌合差距:在現有程式碼庫中使用 React Native
當晚的最後一場演講是 Airbnb 的 Leland Richardson。演講的重點是在現有程式碼庫中使用 React Native。我已經知道使用 React Native 從頭開始編寫新的應用程式有多容易,所以我非常有興趣了解 Airbnb 在其現有原生應用程式中採用 React Native 的經驗。
Leland 首先談到了綠地應用程式與棕地應用程式。綠地意味著開始一個專案,而無需考慮任何先前的工作。這與棕地專案形成對比,在棕地專案中,您需要考慮現有專案的需求、開發流程以及所有團隊的各種需求。
當您在開發綠地應用程式時,React Native CLI 會為 Android 和 iOS 設定一個單一儲存庫,並且一切都能正常運作。Airbnb 使用 React Native 的第一個挑戰是 Android 和 iOS 應用程式各有自己的儲存庫。多儲存庫公司在採用 React Native 之前需要克服一些障礙。
為了繞過這個問題,Airbnb 首先為 React Native 程式碼庫設定了一個新的儲存庫。他們使用持續整合伺服器將 Android 和 iOS 儲存庫鏡像到這個新的儲存庫中。在執行測試並建置套件後,建置成品會同步回 Android 和 iOS 儲存庫。這讓行動工程師可以在不改變其開發環境的情況下開發原生程式碼。行動工程師不需要安裝 npm、執行打包器或記住建置 JavaScript 套件。編寫實際 React Native 程式碼的工程師不必擔心其程式碼在 Android 和 iOS 之間同步,因為他們直接在 React Native 儲存庫上工作。
這確實帶來了一些缺點,主要是他們無法發布原子更新。需要原生和 JavaScript 程式碼組合的變更將需要三個獨立的提取請求,所有這些請求都必須仔細地合併。為了避免衝突,如果自建置開始以來 master 已變更,CI 將無法將變更合併回 Android 和 iOS 儲存庫。這會在高提交頻率的日子(例如,當發布新版本時)造成長時間的延遲。
Airbnb 後來轉向了單一儲存庫方法。幸運的是,這已經在考慮之中,一旦 Android 和 iOS 團隊開始習慣使用 React Native,他們就很樂意加速朝單一儲存庫的方向發展。
這解決了他們在使用分離儲存庫方法時遇到的大部分問題。Leland 確實指出,這確實會對版本控制伺服器造成更大的壓力,這對於小型公司來說可能是一個問題。

導航問題
Leland 演講的後半部分側重於一個我非常關心的主題:React Native 中的導航問題。他談到了 React Native 中大量的導航函式庫,包括第一方和第三方。NavigationExperimental 被認為是一個有前景的工具,但最終並不適合他們的使用案例。
事實上,現有的導航函式庫似乎都不太適合棕地應用程式。棕地應用程式要求導航狀態完全由原生應用程式擁有。例如,如果使用者在呈現 React Native 視圖時會話過期,則原生應用程式應該能夠接管並根據需要呈現登入畫面。
Airbnb 也希望避免在過渡期間用 JavaScript 版本替換原生導航列,因為這種效果可能會很突兀。最初,他們將自己限制在以模態方式呈現的視圖中,但當在他們的應用程式中更廣泛地採用 React Native 時,這顯然會產生問題。
他們決定需要自己的函式庫。該函式庫稱為 airbnb-navigation
。該函式庫尚未開源,因為它與 Airbnb 的程式碼庫緊密相關,但他們希望在年底前發布它。
我不會詳細介紹該函式庫的 API,但以下是一些主要要點:
- 必須提前預先註冊場景
- 每個場景都顯示在自己的
RCTRootView
中。它們在每個平台上以原生方式呈現(例如,iOS 上使用 UINavigationController
)。
- 場景中的主要
ScrollView
應包裝在 ScrollScene
元件中。這樣做可讓您利用原生行為,例如點擊 iOS 上的狀態列以滾動到頂部。
- 場景之間的過渡以原生方式處理,無需擔心效能。
- 自動支援 Android 返回按鈕。
- 他們可以透過 Navigator.Config 無 UI 元件來利用基於視圖控制器的導航列樣式。
還有一些注意事項需要牢記:
- 導航列不易在 JavaScript 中自訂,因為它是原生元件。這是故意的,因為使用原生導航列是此類函式庫的硬性要求。
- 每當 ScreenProps 透過橋接器傳送時,都必須序列化/反序列化,因此如果在此處傳送過多資料,則必須小心。
- 導航狀態由原生應用程式擁有(也是函式庫的硬性要求),因此 Redux 等工具無法操縱導航狀態。
Leland 的演講之後也進行了問答環節。總體而言,Airbnb 對 React Native 感到滿意。他們有興趣使用 Code Push 來修復任何問題,而無需通過 App Store,他們的工程師喜歡 Live Reload,因為他們不必在每次小變更後都等待原生應用程式重新建置。
活動在一些額外的 React Native 新聞中結束:

Meetup 提供了一個與社群中其他開發人員會面和學習的好機會。我期待在未來參加更多的 React Native meetup。如果您參加了這些 meetup,請留意我,並告訴我我們如何才能讓 React Native 更適合您!