使用React Native來撰寫跨平臺的App

mqzx1817 8年前發布 | 58K 次閱讀 ReactNative 移動開發 React Native

React Native 是一個 JavaScript 的框架,用來撰寫實時的、可原生呈現 iOS 和 Android 的應用。其是基于 React的,而 React 是 非死book 的用于構建用戶界面的 JavaScript 庫,但是這里不是給瀏覽器解釋的,而是為移動平臺。換句話說:如果你是一名 web 開發者,你可以使用熟悉的框架和單一的 JavaScript 代碼庫,即 React Native來撰寫清晰的、高效的移動應用。

我們以前都聽說過那些個通用的 app 開發,比如框架 Cordova 和 Titanium,那實際使用 React Native 是一種什么樣的情況了呢?在本文中,我們會解釋 React Native 到底是什么,以及其是如何工作的,再然后我們以撰寫實際的 iOS 和 Android 應用來一探 React Native 究竟。在最后,希望讀者能夠看到有足夠的理由在下一個移動應用中選擇使用 React Native。

那么什么是 React Native?

在我們深入到開發的經歷之前,我們先來探討下 React Native是什么,并花一些時間來講述下它是如何工作的。

也只是 React

React 是用于構建用戶界面,通常是基于 web 的 JavaScript 程序庫。由 非死book 開發并在2013年將其開源,React 已經得到了頗為廣泛的使用。但是其使用的范圍比較狹窄,它僅是用于渲染用戶的應用程序的界面,而不是更大的 MVC 框架。

React 讓開發者們紛涌而至的原因有很多,諸如輕量級、驕人的性能、尤其是可以快速的變更數據。這均與它的組件結構密切相關,它也同樣鼓勵人們去撰寫更加模塊化的、可重用的代碼。

React Native 也只是 React,但是是針對移動設備的。也有一些少許的不一樣的地方,比如開發者需要使用 <View> 組件而不是 <div> , <Image> 代替 <img> 。開發者的體驗多數是一致的。當然,有一些 Objective-C 和 Java 知識是非常有用的,移動開發有其自身的一些頗為棘手的問題(我在多個移動設備上測試過沒有?觸摸屏的目標是否夠大?)。即使是這樣,若是開發者曾經有過在瀏覽器下大 React 經驗的話,開發 React Native 會感覺非常的熟悉,并且不會感到不適應。

它是真正的原生

關于 React Native 最為讓人們稱奇的第一件事就是它是”真正的“原生。其它的用于移動設備的 JavaScript 均是以某種包裝后的 Web 視角封裝了用戶的 JavaScripts 代碼。他們也許也重新實現了一些本地 UI 的行為,諸如動畫之類的,但是用戶寫的仍然是基于 Web 的應用。

在React中,一個組件能夠描述自身的外觀;React 處理后再呈現給用戶。一個非常清晰的抽象層將兩個功能給隔離開來。為了呈現組件給 web,React 使用的是標準的 HTML 標簽。這和抽象層是一個道理,即是“橋”的概念,去讓 React Native 調用實際的 iOS 和 Android 呈現的 API。在 iOS 中,這意味著 React Native 組件呈現給真正的 UI 視圖;在 Android 下,他們也呈現給了本地的視圖。

你將寫出看起來差不多就是標準的 JavaScript、CSS、HTML 代碼。取代編譯為本地代碼,React Native 會將你的應用運行在本地平臺的 JavaScript 引擎中,毋需屏蔽主要的 UI 線程。你獲得了本地的性能、動畫、行為,還不用去寫 Object-C 或 Java。其它諸如 Cordova 或 Titanium 之類的跨平臺應用開發,是無法達到如此級別的本地性能和表現的。

更好的開發者體驗

相比較于 iOS 和 Android 原生的開發,React Native 提供更好的開發者體驗。因為你的程序大多數都是 JavaScript,你可以從 web 開發中汲取大量的經驗,比如能夠立即“刷新”你的應用來查看你代碼的修改。相比于在傳統的應用開發中花很長的時間去等待構建的過程,會讓人感覺這簡直是天賜之物。

另外,React Native 還為開發者提供了智能的錯誤報告和標準的 JavaSript 調試工具,這些讓移動開發更加的順手。

掌控多平臺

React Native 可以平滑的掌控多個平臺。絕大多數的 React Native API 都是跨平臺的,所以開發者只需要去寫 React Native 的組件即可,它可以無縫的運行在 iOS 和 Android 下,臉書聲稱他們的廣告管理應用跨兩個平臺有 87% 的代碼可重用 ,還有,我自己所寫的 flashcard 的代碼沒有任何平臺有關的代碼。

如果開發者打算撰寫特定平臺的代碼,對于 iOS 和 Android 有不同的交互向導,或者干脆點說,開發者想要獲得特定平臺 API 的獨特優勢,也是很容易就可以辦到的。React Native 允許開發者為每個組件指定特定平臺的版本,可以隨意集成到其它 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 組件

一旦準備好了開發環境,那么就可以開始撰寫一些真正的應用程序了。

正如在文章前面所提到的那樣,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 學習》,電子版和紙版均有售賣,可以到 奧姆萊亞馬遜 上找到。你也可以在推ter上關注我,我的賬號是: @brindellev ,我非常期望聽到大家使用 React Native 的經歷以及疑問。

關于作者

Bonnie Eisenman 是來自推ter的工程師,她是 NYC Resistor 黑客空間的成員之一,之前在Codecademy、Fog Creek 軟件以及Google工作過。她也是《 Learning React Native 》一書的作者,《 Learning React Native 》是由 O'Reilly 出版的,介紹使用 JavaScript 來構建原生的 iOS 和 Android 應用的書籍。她也經常在一些研討會上分享演講,從 ReactJS,到 音樂編程,乃至 Arduinos。在空閑時間,她非常享受于學習新的語言,做一些硬件項目,用激光切割巧克力之類的。可以關注她的推ter:@brindelle。

查看英文原文: Writing Cross-Platform Apps with React Native

 

來自: http://www.infoq.com/cn/articles/react-native-introduction

 

 本文由用戶 mqzx1817 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!