【整理】ReactNative快速入門筆記

weixin_34107955發表於2017-06-19
1494908-3b99aa61063c171a.png

ReactNative的文件地址有多個,如果你英文夠好,就去研讀官方的文件吧,
如果讀原文比較吃力,中文官網也是不錯的選擇。

下面是我個人記錄的一些筆記,僅供初學者入門參考

預科

入門React Native前需要了解一下知識,這樣能幫助你更快的掌握RN
Node:Node.js 教程
ReactJS:《React 入門例項教程》
ES6:《ECMAScript 6 入門》

環境

系統環境要求

IOS : MacOS, 黑蘋果
Android :MacOS, Linux, Windows

配置

所有的技術學習都應該從環境搭建開始,這裡也沒什麼好總結的,最好的方法就是跟著官網指導配置環境
如果你是node的老手,那就直接動手安裝以下環境吧:

  • node
  • npm
  • react-native-cli
  • Xcode
    安裝Xcode IDE和Xcode的命令列工具(IOS開發依賴)
  • Android Studio
    下載必須的外掛:
    a) JDK1.8+
    b) Show Package Details
    c) Android SDK Build Tools (指定23.0.1版本)
    d) Android Support Repository
    配置基礎環境:
    a) ANDROID_HOME (如執行是遇到問題可參考此文http://www.jianshu.com/p/a77396301b22
    b) JAVA_HOME

測試

react-native init RNDemo
cd RNDemo
react-native run-ios

如果你的虛擬機器啟動了,那麼恭喜你,你的環境已經配置成功!
如果執行報錯,可以文章最後找尋解決方案。


1494908-279025ab7557c2ad.png
虛擬機器啟動介面

語法

首先需要了解一些基本的React的概念,比如JSX語法、元件、state狀態以及props屬性。
還需要掌握一些React Native特有的知識,比如原生元件的使用。

教程上的東西我就不多說了,官方文件上有詳細的講解

直接從程式碼上講解新手注意點吧

Hello World

傳統慣例,入門先行,Hello World

你可以新建一個專案,然後用上面的程式碼覆蓋你的index.ios.js或是index.android.js 檔案,然後執行看看。

import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text } from 'react-native';
class HelloWorldApp extends Component {
  render() {
    return (
      <Text style={styles.red}>Hello world!</Text>
    );
  }
}
const styles = StyleSheet.create({
  red: {
    color: 'red',
    fontWeight: 'bold',
  }
});
// 注意,這裡用引號括起來的'HelloWorldApp'必須和你init建立的專案名一致
AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp);

從語法上看,RN和ReactJS語法區別不大,都是採用JSX和ES6的形式,如果你對ReactJS和ES6不熟悉,建議你先拜讀下阮一峰的博文教程:《React 入門例項教程》《ECMAScript 6 入門》

相較寫Web App,區別在於RN的語法引入了原生的元件

import { AppRegistry, StyleSheet, Text } from 'react-native';

RN中雖然使用JS寫原生UI,但不再使用常規HTML標籤 <div> 或是 <span> ,而是使用RN的元件 <Text>
AppRegistry 模組寫在index.ios.js或是index.android.js檔案裡,用來告知React Native哪一個元件被註冊為整個應用的根容器,一般一個應用只執行一次。

僅僅使用props和基礎的View、Text、Image以及TextInput元件,就足以編寫各式各樣的UI元件了

樣式

按照JSX的語法要求使用了駝峰命名法:

  • font-weight -> fontWeight
  • background-color -> backgroundColor

React Native中的尺寸都是無單位的,表示的是與裝置畫素密度無關的邏輯畫素點:

<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />

事件

事件的註冊跟ReactJS沒什麼區別

class MyButton extends Component {
  _onPressButton() {
    console.log("You tapped the button!");
  }

  render() {
    return (
      <TouchableHighlight onPress={this._onPressButton}>
        <Text>Button</Text>
      </TouchableHighlight>
    );
  }
}

此處註冊的元件為TouchableHighlight,具體使用哪種元件,取決於你希望給使用者什麼樣的視覺反饋

  • 一般來說,你可以使用TouchableHighlight來製作按鈕或者連結。注意此元件的背景會在使用者手指按下時變暗。
  • 在Android上還可以使用TouchableNativeFeedback,它會在使用者手指按下時形成類似墨水漣漪的視覺效果。
  • TouchableOpacity會在使用者手指按下時降低按鈕的透明度,而不會改變背景的顏色。
  • 如果你想在處理點選事件的同時不顯示任何視覺反饋,則需要使用TouchableWithoutFeedback

常用的事件有:
點選:onPress
長按:onLongPress
縮放:maximumZoomScale,minimumZoomScale

另外關於Props、State、樣式、佈局、事件等知識點的詳解,官方文件上都有詳細的講解,比較基礎,這裡就不做介紹了

跨平臺

'Learn Once,Write Anywhere' and not 'Write Once,Running Anywhere'.

RN並不能算上是真正的跨平臺的語言,雖然可以通過打包實現不同平臺打包不同元件,但是有些元件需要我們針對不同平臺編寫不同程式碼。這就要求我們不用儲備一些原生開發的知識。

工作原理

1494908-35bfd488c9f68fd7.png
通訊示意圖

RN的本質是在兩個模組之間搭建雙向橋樑,讓他們可以相互呼叫和響應,簡單的示意圖為


1494908-21daeeddecceb4eb.png

Native模組

執行在主執行緒上(可能會有些獨立的後臺執行緒處理運算,當前討論中可忽略)
iOS平臺上執行Object-C/Swift程式碼,Android平臺上執行Java/Kotlin程式碼
負責處理UI的渲染,事件響應。

JS模組

執行在JS引擎的JS執行緒上
執行JS程式碼
負責處理業務邏輯,還包括了應該顯示哪個介面,以及如何給頁面加樣式。

Bridge模組

Native和JS模組之間不能直接通訊,只能通過Bridge做序列化和反序列化,查詢模組,呼叫模組等各種邏輯,最終反應到應用上

效能

使用React Native替代基於WebView的框架,使App重新整理可以達到每秒60幀(足夠流暢),並且能有類似原生App的外觀和手感,雖然RN框架已經提供了這個平衡的能力,但平衡點的選擇卻掌握在開發者手中,即便是Native也無法避免開發方式帶來的效能消耗

效能影響原因

業務邏輯執行在JS執行緒上,負責API的呼叫,事件的處理,狀態的更新,而事件的響應UI的變化發生在主執行緒上,60幀/s的頻率要求每一幀的響應處理只有16.67(1000/60)ms,如果超過了16.67ms就會發生丟幀,如果丟幀超過100ms就會產生明顯的卡頓現象。所有降低每一幀運算的消耗才能提升效能。

效能影響切面

UI事件響應: 效能影響小
UI更新: JS側會向Native側同步大量的UI結構和資料,介面複雜、變動資料大,或者做動畫、變動頻繁,容易出現效能問題。
UI事件響應和UI更新同時出現: 兩種事件如果佔用了過多的執行緒,就會導致另一種事件不能及時響應,表現在應用上就是卡頓

常見影響效能的點

console,ListView,動畫Animated

效能優化

經過多年的發展和優化,JS和Native可以在各自的模組執行緒高效迅速的執行,效能的瓶頸主要在Bridge模組上,尤其是在JS和Native模組間頻繁的呼叫會導致Bridge壓力過大,產生卡頓

  1. 利用React自帶的Virtual Dom的Diff演算法儘量減少需要同步的資料,合理利用setState方法
  2. 在遇到動畫效能問題時,可以使用Annimated類的庫,一次性把如何變化的宣告傳送到Native側,Native側根據接收到的宣告自己負責接下來的UI更新。不需要每幀的UI變化都同步一次資料。
  3. Native和JS混編,把會大量變化的元件做成Native元件
  4. 遇到UI事件響應和UI更新同時,可以使用Interaction Manager把那些耗時較長的工作安排到所有互動或動畫完成之後再進行

App高效能開發引導

RN的開發並沒有一種高質量產出的方法,因為各個專案間有著不同的元件組合,因此只能通過高效的開發方式來儘可能的優化應用。
一般來說,通過幾版優化都能達到“極致體驗”的要求。
下面列一下高效開發方式的流水:

  1. 全JS實現,保證開發的高效率,高產出
  2. 發現問題先在JS測做優化,如上面提到的Annimated類庫,Interaction Manager。
  3. 真機測試,找全問題再做處理,避免出現連鎖bug
  4. JS測解決不了的問題再有Native元件完成。

關於熱更新

原理

1、RN是使用指令碼語言來編寫的,是的程式碼可以不用事先編譯便可即讀即執行
2、RN在釋出時將程式碼資源打包成一個檔案 bundle js檔案
3、其他的基礎外掛不變,僅僅替換一個bundle檔案就實現了熱更新

流程

1494908-3137b78a8d860255.jpeg
熱更新的流程圖

Rushy

Rushy是國內RN團隊自主研發的一套熱更新包管理平臺

Pushy的特點:

  1. 命令列工具&網頁雙端管理,版本釋出過程簡單便捷,完全可以整合CI。
  2. 基於bsdiff演算法建立的超小更新包,通常版本迭代後在1-10KB之間,避免數百KB的流量消耗。
  3. 支援崩潰回滾,安全可靠。
  4. meta資訊及開放API,提供更高擴充套件性。
  5. 跨越多個版本進行更新時,只需要下載一個更新包,不需要逐版本依次更新。
1494908-ce179a18769dc745.png

社群

RN同ReactJS一樣,有著強大的社群,從RN版本更新的速度上就可以看出來


1494908-fbf4009e6abf2183.png
釋出序列表

平均2個月一個版本

google的搜尋結果也能說明RN的影響力

1494908-4756846d58fa5844.png
google搜尋結果

開發者需要用到的元件在JS.Coach基本都可以找到。


1494908-22adf87fe0d89395.png
image.png

參考&分享

相關文章