[譯] 一名 iOS 開發者的 React Native 開發經歷

一名 iOS 開發者的 React Native 開發經歷

若是你是一名 iOS 開發者,你應該據說過 React Native。它給出了簡單而吸引人的承諾:一次編寫,兩處部署,同時搞定 iOS 與安卓版本的 app。我是一名資深的 iOS 開發者(仍是一名更資深的 macOS 開發者),我想分享我應用這門神奇技術的經歷。前端

去年,咱們和一個客戶進行過交談。他們來找咱們是由於他們想盡快完成他們的 iOS app。在討論的過程當中,他們提到了這個叫作 React Native 的東西。他們有個善於使用 Javascript 的 web 開發人員,那我的指出使用 RN 可讓開發速度快不少。這場談判最終咱們沒有達成共識而是以失敗了結,但這件事也讓我開始思考是否應該將 RN 歸入咱們的技術棧中react

幾周後一位老友來訪,讓我爲他出版的一本書製做一個 app 做爲補充參考資料。由於這個工做我找到了一線機會:這是一個很棒的時機來試一試 React Native。因爲他的讀者大多數使用安卓系統,所以「一次編寫,兩處部署」的理念在此深得我心。android

我不會帶你親歷一遍個人各類嘗試和遇到的問題。但我要說的是,就這麼一個簡單的 app,並不能使用 RN 很好的進行開發。如下是緣由。ios

首先,我必須說一下除開「一次編寫,兩處部署」的承諾,我喜歡 React Native 的地方。git

  • React.js,RN 由它而生。它是一種描述與更新 UI 的優雅方法。它的基本原理是組件使用一組傳遞給它的屬性由上到下渲染其 UI。感謝 React 的虛擬 DOM,當屬性變化時 UI 會當即更新,使得 model 與 view 可以自動且無縫地同步。我多麼但願 iOS 的 UIKit 也這樣設計啊!
  • 更新 JSX 代碼就能夠在模擬器中更新 app 而不須要從新編譯與從新運行,這點真的很棒。
  • 蓬勃發展的 RN 社區提供了數以百計的預製組件,你能夠在你的 app 中使用它們。(實際上我很是討厭這種看似專業的「腳本小子」的編程方法。構建一個大部分都不是你本身寫的,而且弄不明白的 app,將會致使以後的維護如同陷入泥潭通常困難)
  • 我很擔憂 RN 的性能,可是在個人經歷中它並無出現問題。滾動和動畫都很流暢。畢竟 RN app 大部分使用的是平臺原生的 UI 控件,RN 的工程師們也對它們進行了很好的優化。

那麼爲何我不喜歡它呢?老實說,我並非 React Native 的目標用戶。我熟悉 Javascript 但我並不精通它,我精通的是 Swift/Objective-C。我很快就意識到,若是我使用 RN 來完成這個 app,將會比我用 Swift 慢 10-20 倍。固然,安卓版本還要單獨寫,可是考慮到我學習 RN 的學習曲線,我還不如去學習 Java。程序員

除此以外,我認爲採用 RN 的解決方案還有一些嚴重的問題。github

脆弱的依賴鏈

React Native 並非一個一站式解決方案。我製做了一個粗略的必要組件依賴圖:web


上圖爲React Native 的依賴鏈

若是你來自 web 開發的世界,這可能對你來講很正常;可是對我來講,這很不正常。個人世界中有 Xcode,任何建立 Swift/Obj-C/iOS/Mac/Apple TV 等 app 所須要的東西都已經封裝好並由 Xcode 管理。依賴鏈和前面的圖同樣(甚至更長),可是依賴鏈中的東西都保證是同步且兼容的。編程

我如今確定 RN 依賴鏈中的大多數組件都是互相兼容的。但我遇到了四五個須要在 StackOverflow 上花幾小時尋求解決方案的問題。在我心中更重要的是以後會發生的事情。例如,升級 Nuclide(IDE 的 RN 拓展)可能須要新版的 Atom。我係統中的另外一個工具須要新版的 winston,若是那個版本不兼容 RN 怎麼辦?後果可想而知。json

被打破的承諾

事實證實「一次編寫,兩處部署」的承諾只有部分實現了。我遇到了必需要把個人 RN app 根據目標平臺(iOS 或安卓)進行「分支」的問題。例如 tab bar,你可能認爲像它這麼隨處可見的組件會被 RN 列爲「一等公民」,但事實不是這樣的。RN 爲 iOS 收錄了 TabBarIOS 組件,可是由於某些緣由它在安卓上並不相同。相反,在 GitHub 上有一堆的教程和解決方案教你如何從頭作起。又例如 nav bar,iOS 的 NavigatorIOS 與安卓的 Navigator 工做方式差異巨大。這些核心的導航功能結構在兩個平臺上的差別會致使要爲每一個平臺分別編寫大量的不一樣的文件與組件。我開始感受到,儘管承諾很神奇,儘管我在用同一種語言,但其實我仍然在寫兩個不一樣的 app。

  • 實際上,這個「承諾」實際上是別人推斷的,並非官方宣稱的(至少 Facebook/RN 的人沒有這麼宣稱過)。官方宣傳的是「一次學習,隨處編寫」。

使人驚訝的技術限制

我在作的這個項目實際上是一個層級化的參考指南。書做者和我爲目錄與文章用咱們設計的 UI 範式規劃了一套挺合理的佈局。根據咱們的想法,咱們能夠經過連接或導航跳轉到數百個使用靜態內容的詳情頁中。我寫好了代碼,但奇怪的是我調用 require() 一直不成功。我通過一段時間的研究,瞭解到 RN 限制您沒法從任意路徑讀取文件。顯然你的 RN app 在編譯時收集了全部可能用到的路徑,任何編譯器沒法找到的路徑都將不能讀取。因此你能夠用 require(‘../file1.json’) 但不能用 require(‘../file’ + ‘1’ + ‘.json’)。這個讓人驚訝的限制使得咱們的架構沒法實現。

冒牌貨般的 UI

你最終完成的 RN app 可能既不像原生的 iOS app 也不像原生的安卓 app。大多數用戶可能不會察覺這個問題,但有些人會發現更大的問題。你有可能會丟失一些用戶會注意到的平臺特有的細節,例如不能從左側右滑來返回。(當你用 NavigatorIOS 完成兩個平臺的導航時會出現這個問題)

總而言之,iOS 開發者不該該將 React Native 視爲兩個平臺的跨平臺解決方案。寫一個原生的 iOS app 將會花費更少的時間並可能獲得更棒的 UX。對於安卓 app 也同樣,因此我認爲你們應該更多的去專一於平臺原生解決方案。

何時用 RN 纔是正確的呢?若是你是一個專業的 Javascript 程序員或者你有這麼一個員工,而且你不打算配置 iOS 開發或安卓開發人員,那麼你可能會從中獲益。還記得那個想要儘快作好跨平臺 app 的那個客戶嗎?他們有一名 Javascript 工程師,他們 app 的 v1.0 版本最近纔出如今應用商店中。此時,距他們聯繫咱們已通過去了 8 個月。

最後是無恥的廣告時間!若是你須要人幫你開發 iOS app,請點這裏

掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOSReact前端後端產品設計 等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃

相關文章
相關標籤/搜索