react-native 開發小結(Android)

拉丁吳發表於2016-09-29

在windows上開發react-native已經有一些時候了。作為一個Android原生開發者,在開發的過程中,雖然有點蛋疼,但畢竟積累了一點點經驗,再不說出來,我就要側漏了......

1,前言

react-native開發使用的是JS,但是並不是純正的JS,而是一種JSX語言,就是在JS中嵌入XML語言,因此,只要有一些JS的語法基礎的原生開發者,就可以肯容易理解JSX的語法了,在RN中,推薦使用ES6的語法。

對於JS而言,一切皆物件,函式也是物件,而物件的內部是通過key-value的形式來組成的,也可以說是通過json格式來組成。物件內部每一個鍵值對(key:value)稱作一個屬性(RN中最重要的屬性是state和props)。

2,效能

使用react-native開發的最大的有點在於開發效率,加入APP並不複雜的話,那麼完全可以使用純JS開發,也就是Android和iOS公用一套介面和邏輯。極大的提高了開發效率。在效能上,(Android中一般的操作)RN的表現比原生弱一些,但是遠好於H5。所以總體來看,其實RN的未來還是可以期待的。

3,RN執行機制簡述

RN是執行JS的,Android是執行Java位元組碼的,所以,實際上JS程式碼的最終執行是通過一層封裝,把JS的程式碼對映成原生程式碼,而介面上的元素最終使用的也是原生的元件,而不是自己渲染(所以在效能上,RN比H5要好很多)。

4,Component簡介

在Android中,主要互動容器是activity或Fragment,而在RN中,介面的互動容器是Component:元件。我覺得Component和原生的Fragment其實很像,都存在於activity中,都受制於activity的生命週期,都可解除安裝和裝載。

4.1,Component生命週期

component生命週期

由上圖可知,大致分三個過程:初始化,執行中,解除安裝。

  • 初始化階段:
    • 在新版的Component中ES6語法中,getDefaultProps,getInitialState 是不應該被複寫的。RNAPI要求我們props,state的初始化在Component的constructor函式中完成(props,state這倆大寶貝下文在做解釋),因此在初始化階段可以做的就是在constructor或者componentDidMount函式中完成相關初始化工作。
    • componentDidMount函式是元件第一次繪製完成之後被呼叫的,整個週期只被呼叫一次,在這裡可以做一些網路請求操作等。
  • 執行階段:
    • 重點在於修改state內容,來重新整理介面
  • 解除安裝階段
    • 在componentWillUnmount方法中做一些移除操作,或者什麼都不做。

在這裡,已經有前輩寫出了比較詳細的博文了,有興趣請前往React Native 中元件的生命週期

4.2,state和 prop

這兩個屬性之所以重要,是因為stat和介面的重新整理有關,prop則和元件的封裝有關。

state初始化在建構函式中,通過setState來修改裡面具體的值。具體如下:

state

而修改state內容則是這樣:

setstate

當state中的內容被修改後,當前元件就會按照生命週期來重新整理頁面,這樣,所有和介面重新整理的任務就全部交到state這一個屬性手裡了。這是一個很不錯的設計。

而prop這個屬性,則是用於封裝元件的時候對外暴露元件的可輸入屬性。即就像這樣:

prop示例

就這樣,封裝元件中的所有你想暴露給別人輸入的屬性都可以定義在prop之中。

4.3,component間的跳轉

在原生開發中,介面的跳轉主要依賴Intent作為橋樑,而在RN中,則全部依靠Navigator這個元件來實現頁面之間的跳轉邏輯。

navigator例項

  • initRoute這個屬性指定了初始化的頁面,在這個例子中,進入第一屏的頁面將是TabBarView,
  • configureScene這個屬性用於指定預設跳轉動畫
  • renderScene這個屬性傳入的是一個方法,根據得到的不同的元件(component)來渲染不同的場景。

Navigator這個導航器是全域性的,整個APP中只有一個,會根據介面的跳轉傳遞到每個Component內部的prop中。Navgator會維護一個棧,這一點和原生的Activity的任務棧極其相似,可以對照理解。

  • 資料傳遞 上面的程式碼中有這樣一段:
< Component navigator = {navigator} route = {route}
        {...route.passProps} />複製程式碼

{...route.passProps}保證passProps裡每個key都會被視作prop的一個屬性,具體如下:

跳轉到SecondPageComponent介面

navigator.push({
    name: 'SecondPageComponent',
    component: SecondPageComponent,
    passProps: {   //注意passProps和之前定義的保持一致
        msg:'ladingwu is handsome'
    }
});複製程式碼

而在SecondPageComponent介面介面中,這樣來取資料:

export default class SecondPageComponent extends React.Component {

    componentDidMount() {
            //這裡獲取傳遞過來的引數
            var message=this.prop.msg;
        }
}複製程式碼

怎麼樣,簡單極了吧。當然,在原生開發中,還有startActivityForResylt()這個方法可以再從第二個介面返回時獲取資料,那麼在RN中是否能做到呢?也很簡單,依然是通過傳遞引數,只不過這個時候的引數,應該是一個回撥函式(js中,函式也可以當作引數,一切皆物件)

跳轉到SecondPageComponent介面

navigator.push({
    name: 'SecondPageComponent',
    component: SecondPageComponent,
    passProps: {   //注意passProps和之前定義的保持一致

        getMsg:(msg)=>{console.log(msg)}
    }
});複製程式碼

而在SecondPageComponent介面介面中返回資料:

export default class SecondPageComponent extends React.Component {

    componentDidMount() {
            //這裡獲取傳遞過來的引數
            this.prop.getMsg('ladingwu is still handsome');
        }
}複製程式碼

不要太簡單哦。。。。

5,總結

當然,RN還有很多可以說的,比如動畫(效能有點感人),網路請求,資料儲存等等,就不一一舉例說明了。

說一點感想,使用RN開發這段時間,感覺這玩兒確實可以提高工作效率,畢竟Android和iOS使用一套介面,而且很多功能在RN上都有完備的實現,基本上,只要APP的業務邏輯不復雜,或者並不涉及到很多硬體操作或對效能要求很高的話,使用純RN開發是完全可以的。假如H5是未來的話,那麼在未來來臨之前,RN才是更好的選擇,當然,RN並不能完全取代原生開發,因為它只是在原生和H5之間找平衡的產物,它當然好,但也不是最優解。

你是不是該學?

應該,即使只是衝著JS也要去學一把,如今,JS不僅霸佔了web端,還入侵了移動端和後臺開發,我就問你怕不怕?


最後推薦幾個學習RN必備網站:

React-Native中文站(非官方)

React-Native官方網站

江清清的技術專欄

google搜尋引擎

相關文章