React Native 是一個 JavaScript 的框架,用來撰寫實時的、可原生呈現 iOS 和 Android 的應用。其是基於 React的,而 React 是 Facebook 的用於構建用戶界面的 JavaScript 庫,可是這裏不是給瀏覽器解釋的,而是爲移動平臺。換句話說:若是你是一名 web 開發者,你可使用熟悉的框架和單一的 JavaScript 代碼庫,即 React Native來撰寫清晰的、高效的移動應用。javascript
咱們之前都據說過那些個通用的 app 開發,好比框架 Cordova 和 Titanium,那實際使用 React Native 是一種什麼樣的狀況了呢?在本文中,咱們會解釋 React Native 究竟是什麼,以及其是如何工做的,再而後咱們以撰寫實際的 iOS 和 Android 應用來一探 React Native 究竟。在最後,但願讀者可以看到有足夠的理由在下一個移動應用中選擇使用 React Native。css
在咱們深刻到開發的經歷以前,咱們先來探討下 React Native是什麼,並花一些時間來說述下它是如何工做的。html
React 是用於構建用戶界面,一般是基於 web 的 JavaScript 程序庫。由 Facebook 開發並在2013年將其開源,React 已經獲得了頗爲普遍的使用。可是其使用的範圍比較狹窄,它僅是用於渲染用戶的應用程序的界面,而不是更大的 MVC 框架。java
React 讓開發者們紛涌而至的緣由有不少,諸如輕量級、驕人的性能、尤爲是能夠快速的變動數據。這均與它的組件結構密切相關,它也一樣鼓勵人們去撰寫更加模塊化的、可重用的代碼。react
React Native 也只是 React,可是是針對移動設備的。也有一些少量的不同的地方,好比開發者須要使用<View>
組件而不是<div>
,<Image>
代替<img>
。開發者的體驗多數是一致的。固然,有一些 Objective-C 和 Java 知識是很是有用的,移動開發有其自身的一些頗爲棘手的問題(我在多個移動設備上測試過沒有?觸摸屏的目標是否夠大?)。即便是這樣,如果開發者曾經有過在瀏覽器下大 React 經驗的話,開發 React Native 會感受很是的熟悉,而且不會感到不適應。linux
關於 React Native 最爲讓人們稱奇的第一件事就是它是」真正的「原生。其它的用於移動設備的 JavaScript 均是以某種包裝後的 Web 視角封裝了用戶的 JavaScripts 代碼。他們也許也從新實現了一些本地 UI 的行爲,諸如動畫之類的,可是用戶寫的仍然是基於 Web 的應用。android
在React中,一個組件可以描述自身的外觀;React 處理後再呈現給用戶。一個很是清晰的抽象層將兩個功能給隔離開來。爲了呈現組件給 web,React 使用的是標準的 HTML 標籤。這和抽象層是一個道理,便是「橋」的概念,去讓 React Native 調用實際的 iOS 和 Android 呈現的 API。在 iOS 中,這意味着 React Native 組件呈現給真正的 UI 視圖;在 Android 下,他們也呈現給了本地的視圖。ios
你將寫出看起來差很少就是標準的 JavaScript、CSS、HTML 代碼。取代編譯爲本地代碼,React Native 會將你的應用運行在本地平臺的 JavaScript 引擎中,毋需屏蔽主要的 UI 線程。你得到了本地的性能、動畫、行爲,還不用去寫 Object-C 或 Java。其它諸如 Cordova 或 Titanium 之類的跨平臺應用開發,是沒法達到如此級別的本地性能和表現的。git
相比較於 iOS 和 Android 原生的開發,React Native 提供更好的開發者體驗。由於你的程序大多數都是 JavaScript,你能夠從 web 開發中汲取大量的經驗,好比可以當即「刷新」你的應用來查看你代碼的修改。相比於在傳統的應用開發中花很長的時間去等待構建的過程,會讓人感受這簡直是天賜之物。github
另外,React Native 還爲開發者提供了智能的錯誤報告和標準的 JavaSript 調試工具,這些讓移動開發更加的順手。
React Native 能夠平滑的掌控多個平臺。絕大多數的 React Native API 都是跨平臺的,因此開發者只須要去寫 React Native 的組件便可,它能夠無縫的運行在 iOS 和 Android 下,臉書聲稱他們的廣告管理應用跨兩個平臺有87% 的代碼可重用,還有,我本身所寫的 flashcard 的代碼沒有任何平臺有關的代碼。
若是開發者打算撰寫特定平臺的代碼,對於 iOS 和 Android 有不一樣的交互向導,或者乾脆點說,開發者想要得到特定平臺 API 的獨特優點,也是很容易就能夠辦到的。React Native 容許開發者爲每一個組件指定特定平臺的版本,能夠隨意集成到其它 React Native 的應用當中。
使用單一的 JavaScript 庫就想寫出真正的原生的 iOS 和 Android 的應用來,無異於異想天開。那麼 React Native 又是如何作到的了呢?
要開始開發 React Native 應用程序,須要爲 iOS 和 Android 的開發安裝一些常見的依賴,即便是 React Native。在 React Native 官方站點上有很是好的指南。設置 React Native 其實蠻簡單,若是開發者已經安裝了最新版的 Node.js 的話,只須要執行命令 npm install -g react-native-cli
就能夠安裝 React Native了。
一旦這些相關的依賴安裝完成後,運行 react-native init ProjectName
,此命令會自動生成開發者開始一個項目所須要的全部樣板。
這裏有一點須要特別注意:開發 React Native 的話須要使用 OS X 操做系統。開發 iOS 應用,蘋果公司強制要求使用 Mac,這一點對於大多數開發人員來講這個限制已經不可避免。若是開發者是專門撰寫 Android 應用的話,React Native 還支持 Windows 和 Linux 平臺,不過目前尚處於試驗階段,開發者不妨嘗試一下。
一旦準備好了開發環境,那麼就能夠開始撰寫一些真正的應用程序了。
正如在文章前面所提到的那樣,React Native 真的也只是 React,只是有少量不一樣罷了。React Native 的組件在瀏覽器中看的話和 React 的組件及其類似,可是基本的構建塊已經變了。諸如<div>
、<img>
、<p>
等標籤均被替代了,React Native 提供給開發者一些諸如<Text>
、<View>
等基本的組件,在下面的例子中,基本的組件使用的是<ScrollView>
、<TouchableHighlight
、以及<Text>
,全部這些都會映射到 iOS 和 Android 特定的視圖,使用它們建立帶有觸摸控制屬性的滾動視圖是很是直接的:
// iOS & Android var React = require('react-native'); var { ScrollView, TouchableHighlight, Text } = React; var TouchDemo = React.createClass({ render: function() { return ( <ScrollView> <TouchableHighlight onPress={() => console.log('pressed')}> <Text>Proper Touch Handling</Text> </TouchableHighlight> </ScrollView> ); }, });
若是你沒有處理過雜亂無章的 HTML-esque 語法以及 JSX 之前的 JavaScript 的話,這可能對你有一些困惑。React 強烈推薦開發者使用 JSX,那麼基於 React Native 的話,其實沒有什麼能夠選擇的機會。你渲染的標記是和 JavaScript 所控制的行爲共存的。就這一點來講常會引發新接觸者強烈的反感,可是我仍是強烈建議不妨一試。
由於 React Native 的組件和常見的 React 的組件極爲相似,因此切換到 React Native相對是很容易的。
爲了讓渲染更容易、更加的有效,一樣鼓勵維護樣式代碼,React Native 實現了一個嚴格的 CSS 的子集。這同時也意味着開發者無需去學習特定平臺的方法來從而設計視圖,固然,開發者仍是要花點時間去學習如何使用 React Native 的樣式表的。
最大的不一樣就在於開發者不須要去擔憂特定的規則,由於樣式的繼承是被嚴重削弱過的,並且 React Native 使用的內聯樣式的語法。
這裏是一個如何使用 React Native 來建立樣式表的實例:
var styles = StyleSheet.create({ container: { flex: 1, marginTop: 30 } });
而後,此種樣式是由內聯語法所應用的:
<View style={styles.container}> ... </View>
語法是至關的容易閱讀,可是若是開發者是來自於 Web 開發的背景的話,可能會發現有些不妥。(會有一個好的理由讓你繼續下去的,我保證!)即進一步去閱讀關於 CSS,就會發現問題,如果以 React 的方法來解決它們的話,我這裏強烈推薦 Christopher Chedeau 演示文稿:JS 中的 CSS。
React Native 的其中一個比較複雜的部分就是開發環境的設置。當基於 React Native 工做時,開發者針對移動開發須要全部的一般的工具,以及 JavaScript 編輯工具:一個文本編輯器,可能還須要 Chrome 的開發者調試工具。
對於 iOS 來講,這也就意味着須要開着 Xcode,以及 iOS 模擬器。對於 Android 來講,也須要開着的有 Android Studiom、將會用到的命令行工具。最終,開發者還須要運行着的 React Native 包,固然,開發者能夠自行決定使用本身喜歡的文本編輯器來編輯 JavaScript 代碼。
這麼作的後果就是你須要在本身的本地開好多窗口,如此之多的工具,桌面雜亂到着實讓人煩惱,可是,這樣的 React Native 不會隱藏任何標準的移動開發過程。
React Native 工做在已有平臺的上 API 所提供的 JavaScript 接口上。在實踐中,這意味着開發者能夠撰寫原先本身熟悉的 React 代碼,React Native 的「橋」會自動完成相關的轉換,可是若轉換的功能不夠完善沒有完全搞定的時候該如何處理?
不可避免的是,基於諸如 React Native 這樣的新框架來開發的話,總會有一些 API 是不被支持的。若發生了這樣的事情,你就須要撰寫「本地的模塊」來提供主機平臺和所開發的 JavaScript 代碼之間的通訊。下面是一個關於 Objective-C 模塊的 「Hello,World」的簡易實例:
// Objective-C #import "RCTBridgeModule.h" @interface MyCustomModule : NSObject <RCTBridgeModule> @end @implementation MyCustomModule RCT_EXPORT_MODULE(); // Available as NativeModules.MyCustomModule.processString RCT_EXPORT_METHOD(processString:(NSString *)input callback:(RCTResponseSenderBlock)callback) { callback(@[[input stringByReplacingOccurrencesOfString:@"Goodbye" withString:@"Hello"]]); } @end
而後,要使用開發者本地的 JavaScript 模塊的話,和須要其它的庫是同樣的:
// JavaScript var React = require('react-native'); var { NativeModules, Text } = React; var Message = React.createClass({ getInitialState() { return { text: 'Goodbye World.' }; }, componentDidMount() { NativeModules.MyCustomModule.processString(this.state.text, (text) => { this.setState({text}); }); }, render: function() { return ( <Text>{this.state.text}</Text> ); } });
開發者這樣作多是由於所須要的 API 尚未獲得支持,又或者是集成 React Native 組件到現有的 Objective-C 或 Java 代碼中,又或者是須要寫一些高性能的功能來處理一些密集的圖形處理。很是值得慶幸的是,React Native 已經可以提供很是靈活的撰寫和使用這些稱之爲「原生模塊」,只要開發者須要,並且流程也是很順溜的。哪怕是開發者歷來沒有 Objective-C 或 Java 的開發經驗,撰寫「橋」的代碼是在和本地的移動開發至關舒服的狀況下的一種很爽的體驗。
部署 React Native 的應用工做原理和傳統的移動應用部署方式及其的相似,這並非說這會很是的容易,衆所周知,移動應用的發佈流程是很是使人煩惱的。
要建立一個準備好部署的包,開發者須要使用打包好的 JavaScript 來代替在線重載的開發版本。在 iOS 中,這意味着須要在 AppDelegate.m
文件中更改一行代碼,而後運行 react-native bundle --minify
。對於 Android來講,開發者須要運行 ./gradlew assembleRelease
,在這以後,打包的流程就和原來的移動開發過程沒有任何的區別了,且最終的打包結果會提交到相關的應用程序商店中。
個人 flashcard 應用在 iOS 應用商店花了兩週的時間,在 Google Play 商店花了不到一天的時間。換句話說,批准的時間徹底符合個人預期,即和「傳統的」移動應用沒有任何區別,對於 React Native 所寫的程序沒有做任何的處罰。
有趣的是,蘋果容許應用自行更新--所以繞過了使人頭疼的部署過程--若是隻是更新 JavaScript的話。微軟最近釋出了CodePush SDK,其容許 React Native 開發者當即更新。這是一個很是好的特性,我但願在接下來的幾個月當中可以看到更多的應用程序享用此特性所帶來的便捷。
若是你的背景是基於 web 開發的 JavaScript 工程師的話,我覺得你會爲 React Native 而高興的。React Native 能夠將任何背景的 web 開發者轉變爲潛在的移動開發者,並且對於現有的移動開發流程是獲得了有效的改進。
固然,React Native 也不是天衣無縫的,畢竟她仍是一款較新的軟件項目,要經受哪些不夠成熟的程序庫的折磨:有一些特性仍是缺失的。並且最佳實踐之類的還尚待挖掘。版本之間的變化太過於跳躍,雖然不多發生並且範圍也比較有限,但仍是偶爾會發生。
然而,React Native 已經足夠的成熟,總而言之,好處是遠遠大於瑕疵的。基於 React Native,開發者可使用單一的 JavaScript 代碼庫來建立 iOS 和 Android 的應用,並且尚未質量和性能上的損耗。即便開發者沒有 JavaScript 的背景,也很難不被更加快速的開發週期和幾乎徹底的代碼重用這樣的好處所吸引。並且由於 React Native 容許開發者在須要的時候切換到「常見」的開發狀態,你還不會受限於框架。總而言之,React Native 交付了一款高質量的、跨平臺的移動開發工具,若是讀者你要加入到移動開發的項目中來,你須要慎重的考慮下使用 React Native。
若是你想更進一步的閱讀,我已經出版了一本專門、詳細的圖書:《React Native 學習》,電子版和紙版均有售賣,能夠到奧姆萊 和亞馬遜上找到。你也能夠在Twitter上關注我,個人帳號是:@brindellev,我很是指望聽到你們使用 React Native 的經歷以及疑問。
國內:
Facebook在3.26 F8大會上開源了React Native,本文是對React Native的技術背景、規劃和風險的概述。
組裏的同窗於4.2完成了天貓iPad客戶端「猜你喜歡」業務的React Native改造(4月中發版)。本週開始陸續放出性能/體驗、穩定性、擴展性、開發效率等評估結果。
圖1 - 4.2已完成React Native改造的業務
What we really want is the user experience of the native mobile platforms, combined with thedeveloper experience we have when building with React on the web.
摘自3.26 React Native的發佈稿,加粗的關鍵字傳達了React Native的設計理念:既擁有Native的用戶體驗、又保留React的開發效率。這個理念彷佛迎合了業界普片存在的痛點,開源不到1周github star破萬,目前是11000+。
圖1 - React Native github
React Native項目成員Tom Occhino發表的React Native: Bringing modern web techniques to mobile詳細描述了React Native的設計理念。Occhino認爲儘管Native開發成本更高,但現階段Native仍然是必須的,由於Web的用戶體驗仍沒法超越Native:
Occhino沒提到的還有Native能實現更豐富細膩的動畫效果,歸根結底是現階段Native具備更好的人機交互體驗。筆者認爲這些例子是有說服力的,也是React Native出現的直接緣由。
圖2 - Occhino在F8分享了React Native(Keynote)
「Learn once, write anywhere」一樣出自Occhino的文章。由於不一樣Native平臺上的用戶體驗是不一樣的,React Native不強求一份原生代碼支持多個平臺,因此不提「Write once, run anywhere」(Java),提出了「Learn once, write anywhere」。
圖3 - 「Learn once, write anywhere」
這張圖是筆者根據理解畫的一張示意圖,自下而上依次是:
前文多處提到的React是Facebook 2013年開源的Web開發框架,筆者在翻閱其2013年發佈稿時,發現這麼一段:
圖4 - 摘自React發佈稿(2013)
React自己也是個龐大的話題再也不展開,詳見React wiki。
筆者認爲「Write once, run anywhere」對提高效率仍然是必要的,而且和「Learn once, write anywhere」也沒有衝突,咱們內部正在改造已有的組件庫和HybridAPI,讓其適配(補齊)React Native的組件,從而寫一份代碼能夠運行在iOS和Web上,待成熟後開源出來。
下圖展現了業務和技術爲React Native所作的改造:
圖5 - 業務和技術改造
自下而上:
更多詳細規劃和進展,以及性能、穩定性、擴展性的數據隨後放出。
React Native相對於Webview和Native的優點和劣勢 @berg 也給出了較詳細的描述,能夠相互參照。