慢牛系列三:React Native實踐

來源:互聯網
上載者:User

標籤:

上次發布了我的慢牛股票APP之後,有園友反饋有點卡,這個APP是基於Sencha Touch + Cordova開發的,Sencha本身是一個比較重的架構,在Chrome裡運行效能還是不錯的,但是在Android的WebView裡,效能受限於機器的配置,在我的小米2s裡表現還行,在小米4s裡開起來比較流暢,但是Android機型相比IOS太多樣了,Sencha Touch在iOS裡表現不錯,不過我還沒編譯iOS版本。 

後來我又試著用了下Ionic架構,基於AngularJs開發,這個架構要輕量,在慢牛股票的公眾號裡試著開發了幾個頁面,感覺很不錯,本來想用AngularJs重新做一個APP,但是後來又接觸了React Native,試著用了下,React Native的編程體驗類似於Sencha Touch,完全的組件化,JSX的文法很有意思,逐步習慣以後,用起來也很順手。

有興趣的朋友可以對比下這三個方案,我留下這個三個方案的:

慢牛股票APP(Sencha Touch+ Cordova)方案

慢牛公眾號(Ionic方案)

Demo(React Native方案) 

動畫:

 

React Native相比上面兩種,體驗更順暢,當然,原生的應用肯定是比在WebView裡體驗好的,ReactNative結合了原生開發和Web開發優勢,不過,React Native現在對Android的支援不算太好,比如動畫。

ReactNative的Flex布局,組件化思想很不錯,上手快,不過因為最終顯示的是原生,所以還是要多瞭解下原生的開發,必要時自己做橋接,比如我在做K線圖,苦於找不到相關的組件,只有自己橋接了MPAndroidChart。

Demo主要實現了幾個我認為比較關鍵功能:

1、導航

2、列表

3、下拉重新整理

4、圖表

這幾個功能點實現以後,後面的工作就輕鬆得多了,比如表單提交,第三方登入,設定等等頁面。

下面說下這幾個點的實現方式,

1、導航

側滑菜單

熟悉原生開發的同學一看就知道,這是原生的DrawerLayout,通過RN橋接過來, 很滑,很順,之前用CSS3在WebView裡做過側滑菜單,當然比不上這個啦!

頁面切換

利用了RN的Navigator組件,這個組件實現了一個Stack,每次新開頁面就是向Stack裡Push新的UI導航資訊,然後在Render時判斷要顯示哪個UI組件,這個導航組件會把曆史UI移動可視範圍之外,利用Opacity把UI設定為透明,然後絕對位置到可視範圍之外,返回時,再把曆史UI移動可視範圍,這樣,曆史UI的狀態還是保持的,這樣的導航在Web上也是可以借鑒的。

這個導航還可以設定轉場動畫,看原始碼,確實是實現了不少的動畫,包括PushFromRight,FloatFromRight,FadeAndroid等,但是設定後不起作用,只有FadeAndroid有效果,但是動畫一閃而過,不順滑,這裡對Android的支援不太好,或者是我的哪裡設定不對?

Tab切換

Tab切換做起來比較容易,不過有一點,在頁面切換過程中,不要重新Render每個Tab對應的內容,重新Render會清除頁面的當前的狀態,比如捲軸的位置等,而且效能差,借鑒Navigator,把非焦點的Tab頁面移動可視範圍之外即可。

Demo中按鈕的表徵圖都是向量的,表徵圖字型的優點不用說了,原生系統也可以用表徵圖字型了,對不喜歡用圖片的同學真是一個喜訊,一想到要做那麼多圖片,要考慮每種解析度,就頭腦哇,這裡用了github上的一個開源組件react-native-icons。

 貼段代碼:

  render: function() {    var navigationView = (      <SideMenu onItemSelected={this.onItemSelected}/>    );    return (      <DrawerLayout        ref="drawerMenu"        drawerWidth={300}        drawerPosition={DrawerLayout.positions.Left}        renderNavigationView={() => navigationView}>            <Navigator            ref=‘navigator‘            debugOverlay={false}            style={styles.appContainer}            configureScene={(route) =>Navigator.SceneConfigs.FloatFromRight}            initialRoute={{name:‘main‘,component:(<TabPanel/>)}}            renderScene={(route, navigator) => {                          return (route.component);            }}          />      </DrawerLayout>);

2、列表:

Demo裡我實現了一個股票的列表,列表拆分成了List組件和ListItem組件,利用React開發,組件化思想很重要,這在之前用Sencha時也有這樣的體驗。

列表這裡沒有用ListView組件,是用ScrollVIew包了一個ListTtem的列表,如果資料量比較大,或者比較複雜列表,可以用官方的ListView來做,效能會比較好,每次更新只會更新變化的清單項目,也提供了分類,設定表頭和表尾等等。

貼段代碼:

  createRows:function(){    return  this.state.myStockList.map(function (obj) {      return (<StockItem key={obj.code} id={obj.code} data={obj}></StockItem>);    });  },   render: function() {    return (       <SwipeRefreshLayout           ref={(control)=>{this._view=control}}           style={styles.scrollView}           onRefresh={this.reloadData}>               <ScrollView style={{flex:1}}>              {this.createRows()}            </ScrollView>        </SwipeRefreshLayout>    );  }

  

3、下拉重新整理:

在github上,有不少的下拉重新整理組件,比如;react-native-gifted-listview,但是都是iOS上可以下拉,在Android上有Bug,文檔上這樣解釋:

Pull-to-refresh in Android (tried to implement it but it seems that onResponderRelease event is not catchable yet in Android ListView - React-Native

關於如何在RN裡響應手勢,我還沒怎麼瞭解,後面再動畫方面多研究下,因為瞭解下原生控制項的橋接,所有就偷懶了,把原生的SwipeRefreshLayout控制項做了橋接,包裹上ScrollVIew,就可以實現下拉重新整理了,在JS裡響應SwipeRefreshLayout發送的重新整理事件,同時開放一個關閉重新整理的介面,JS端擷取資料更新後,關閉重新整理狀態。

4、圖表

圖表這裡,我花的時間最多,目前也不是很完善,只不過,可以顯示K線了,但是在互動上還是要加強。

之前在Web端做過兩次K線圖,一個是Sencha的,一個是D3的,用了RN以後,之前的圖表都用不上了,也考慮過套個WebView,用D3來做,但是效果肯定不好哇,最後還是學習了原生開發,學習了原生UI的布局,組件的繼承架構,學習使用MPAndroidChart組件,如何橋接原生組件等等,收穫不小,現在開發一邊開啟Android Studio,一邊開啟Sublime。。。

原生的組件,View是所有UI組件的基類,而 ViewGroup是容納這些組件的容器,其本身也是從View派生出來的,RN提供了兩種ViewManager類用來橋接這兩類組件,ViewManager管理組件的建立,布局,以及屬性設定,事件觸發。

貼段代碼:

android端(橋接圖表程式碼片段):

public class MPBarLineChartManager extends SimpleViewManager<BarLineChartBase> {    private String CLASS_NAME="MPBarChart";       @Override    public String getName() {        return this.CLASS_NAME;    }    @Override    protected BarLineChartBase createViewInstance(ThemedReactContext reactContext) {        BarChart chart=new BarChart(reactContext);        return  chart;    }    @ReactProp(name="touchEnabled",defaultBoolean = true)    public void setTouchEnabled(BarLineChartBase chart,boolean enable){        chart.setTouchEnabled(enable);    }
   ......}

js端:

var { requireNativeComponent,PropTypes } = require(‘react-native‘);var iface = {  name: ‘BarChart‘,  propTypes: {  data:PropTypes.object,  touchEnabled:PropTypes.bool,  ......scaleX: PropTypes.number,scaleY: PropTypes.number,translateX: PropTypes.number,translateY: PropTypes.number,rotation: PropTypes.number,  },};module.exports = requireNativeComponent(‘MPBarChart‘, iface);

  

這個圖表的橋接項目我發布到了github上,目前實現了對柱狀圖,線形圖,以及組合圖的橋接。

https://github.com/hongyin163/react-native-mpchart

有希望用圖表的同學可以利用下,要是能繼續幫忙增強就更好啦!

 

學會了橋接原生組件以後,我就陷入了一種模式,只要在RN裡實現有難度的,我就想橋接一個原生的Android組件,雖然知道這樣不太好,因為如果用了太多原生的組件,後續的遷移麻煩了,當然最好利用官方提供的Android和IOS都支援的組件,最好是用平台無關的方式來做,這裡最大的感觸是,RN提供了一種途徑,讓js可以和原生組件互動,商務邏輯寫在js裡,利用原生組件呈現,如果有原生開發的同學支援,那麼利用RN開發就方便多了,提供一致的組件庫,一套代碼就可以在兩個系統上運行了,這樣就不僅僅是learn once write anywhere了。

 

關於效能最佳化:

1、消極式載入

  如果一次載入太多的組件,RN需要等全部組件渲染完成才顯示出來,會有白屏,所有每次載入組件最好少一些,比如先構建頁面的架構,架構渲染完成後再載入資料,建立基於資料的組件,或者利用setTimeout消極式載入其他的組件。

2、使用setNativeProps

  React把組件當成狀態機器,通常是用setState方法,改變組件狀態,頁面會重新渲染,但是重新渲染效能比較差,setNativeProps可以繞過這個過程,直接修改原生組件的屬性,或者調用原生的組件的API,效能就好多了,但是狀態同步方面就要多考慮下了。

3、實現shouldComponentUpdate方法

  React在組件渲染時會有個diff演算法,如果前後Virtual DOM狀態改變,會重新渲染組件,如果實現shouldComponentUpdate方法,返回false,就會避免不必要的diff計算和渲染。

 

關於React,這篇文章把他的前世今生都說了,寫得很好:通往全棧工程師的捷徑 —— react

React真是無所不在了,React-DOM,React-Canvas,React-Native,看起來前途無量哇!

最後,大家可以關注慢牛股票的公眾號:

發送react,可以擷取demo的apk檔案,安裝體驗。

 

這個項目的源碼後續會提交到github上,文章寫的一般,見諒!歡迎大家評論留名^_^

關於我的兼職創業曆程

慢牛系列一:如何抓取股票資料

慢系系列二:前端技術選擇

慢牛系列三:React Native實踐

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.