1. 程式人生 > >react-native-redux 簡易教程

react-native-redux 簡易教程

一、React-Native介紹

簡介:
React Native (簡稱RN)是Facebook於2015年4月開源的跨平臺移動應用開發框架,是Facebook早先開源的UI框架 React 在原生移動應用平臺的衍生產物,目前支援iOS和安卓兩大平臺。RN使用Javascript語言,類似於HTML的JSX,以及CSS來開發移動應用。
React-native特點:
1、React Native使你能夠在Javascript和React的基礎上獲得完全一致的開發體驗,構建世界一流的原生APP。
2、React Native著力於提高多平臺開發的開發效率 —— 僅需學習一次,編寫任何平臺。(Learn once, write anywhere)
React Native比起標準Web開發或原生開發能夠帶來的三大好處:


1、手勢識別:基於Web技術(HTML5/JavaScript)構建的移動應用經常被抱怨缺乏及時響應。而基於原生UI的React Native能避免這些問題從而實現實時響應。
2、原生元件:使用HTML5/JavaScript實現的元件比起原生元件總是讓人感覺差一截,而React Native由於採用了原生UI元件自然沒有此問題。
3、樣式和佈局:iOS、Android和基於Web的應用各自有不同的樣式和佈局機制。React Native通過一個基於FlexBox的佈局引擎在所有移動平臺上實現了一致的跨平臺樣式和佈局方案。

二、環境搭建

三、Android中整合React-Native

1、Android原生專案整合React Native
http://blog.csdn.net/u013718120/article/details/55050900?locationNum=15&fps=1
1、建立Android工程:ImitateZhiHu
2、工程建立完畢後,切換到Android Studio的terminal命令列視窗,執行npm init命令,將工程初始化為一個react-native工程(npm init 會生成package.json檔案,即RN的配置文,一個檔案要被其它模組作為工具包引用,一定要有個package.json

{
  "name": "kit"
, "version": "1.0.0", "description": "imittezh' react-native uikit", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [ "charles", "zh", "native", "uikit" ], "author": "charles", "license": "ISC" }

3、執行npm install –save react react-native 命令
4、建立.flowconfig檔案(可以從其它工程複製)
5、在package.json中新增”start”: “node node_modules/react-native/local-cli/cli.js start”,作用:使得在AndroidStudio中可以支援npm命令
6、新增index.android.js檔案,也就是你的RN介面到根目錄下,它是一個入口檔案
7、其它:給專案新增依賴包,網路許可權,NDK支援,maven庫的本地路徑等
8、以上完成之後,react-native就算整合到了專案中了

四、React-Native工程介紹

4.1、工程目錄

工程目錄

4.2、react-native

4.2.1、react-native的生命週期

react-native的生命週期
生命週期的三個階段
第一階段:是元件第一次繪製階段,如圖中的上面虛線框內,在這裡完成了元件的載入和初始化;
第二階段:是元件在執行和互動階段,如圖中左下角虛線框,這個階段元件可以處理使用者
互動,或者接收事件更新介面;
第三階段:是元件解除安裝消亡的階段,如圖中右下角的虛線框中,這裡做一些元件的清理工作
生命週期中一些重要方法
1、getInitialState
該函式用於對元件的一些狀態進行初始化,該狀態是隨時變化的(也就是說該函式會被多次呼叫),比如ListView的datasource,rowData等等,同樣的,可以通過this.state.XXX取該屬性值,同時可以對該值進行修改,通過this.setState修改,es6中將屬性的初始化放到了建構函式中。
2、render
該函式元件必有的,通過返回JSX或其他元件來構成DOM,換言之,就是元件的核心渲染過程。
3、componentDidMount
在元件第一次繪製之後,會呼叫componentDidMount,通知元件已經載入完成。
4、shouldComponentUpdate
當元件接收到新的屬性和狀態改變的話,都會觸發呼叫shouldComponentUpdate(…)

4.2.2、hello world
import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';

export default class MyFirstRNDemo extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.android.js
        </Text>
        <Text style={styles.instructions}>
          Double tap R on your keyboard to reload,{'\n'}
          Shake or press menu button for dev menu
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('MyFirstRNDemo', () => MyFirstRNDemo);

1、第一行 import 引入了 React庫,React是Facebook開發的一款JS庫,主要用於構建那些資料會隨時改變的大型應用,第二行:import {…} from ‘react-native’ 大括號內是一些元件,用於引入一些元件react-native。
2、class FirstRNDemo 就是我們App介面中要展示的內容了,我們可以看到裡面有一個render()方法,這是Component類的一個方法用於渲染介面,他負責將其return回來的View渲染出來。
3、StyleSheet:樣式管理類,類似於css,用於定義一些樣式
4、AppRegistry模組,是用來告知React Native哪一個元件被註冊為整個應用的根容器。
使用AppRegistry.registerComponent進行註冊自己,然後原生系統就可以進行載入執行bundle檔案包,最後就會可以呼叫AppRegistry.runApplication進行執行起來應用

4.2.3、props和state

React 把元件看成是一個狀態機(State Machines)。通過與使用者的互動,實現不同狀態,然後渲染 UI,讓使用者介面和資料保持一致。
一個標準的React元件會由以下幾種情況觸發render。一種是通過setState方法設定了state內容,另一種是外部傳入了props。
props和state狀態變化
props:大多陣列件在建立時就可以使用各種引數來進行定製。用於定製的這些引數就稱為props(屬性),比如我們可以實現指定一個標題欄名字,或者一張圖片的預設地址。
state:我們使用兩種資料來控制一個元件:props和state。props是在父元件中指定,而且一經指定,在被指定的元件的生命週期中則不再改變。 對於需要改變的資料,我們需要使用state。一般來說,你需要在constructor中初始化state(譯註:這是ES6的寫法,早期的很多ES5的例子使用的是getInitialState方法來初始化state,這一做法會逐漸被淘汰),然後在需要修改時呼叫setState方法。

class Bananas extends Component {
  render() {
    let pic = {
      uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
    };
    return (
      <Image source={pic} style={{width: 193, height: 110}} />
    );
  }
}
4.2.4、簡易計數器

簡易計數器

export default class SimpleCounter extends Component {
  constructor(props){
    super(props);
    this.state = {
      mainText: 'init value',numValue: 1
    }
  }
  render() {
    let title = 'React Native介面';
    return (
      <View underlayColor = '#ddd', style={styles.container}>
        <Text >{title}</Text>
        <Text style={styles.welcome}
        onPress={() => this.addNum()}>{this.state.mainText}</Text>
      </View>
    );
  }
  addNum(){
    this.state.numValue ++;
    if(this.state.numValue % 2 == 0){
      this.setState({
        mainText: "Value : " + this.state.numValue + " X"
      });
    }else{
      this.setState({
        mainText: "Value : " + this.state.numValue + " Y"
      });
    }
  }
}

4.3、react與redux

4.3.1、安裝redux依賴包

跟安裝其它依賴庫一樣,通過npm install 命令進行安裝,npm install –save react-dedux

4.3.2、Redux 簡介

redux和 React 之間沒有關係。Redux 支援 React、Angular、Ember、jQuery 甚至純 JavaScript。Redux對於JavaScript應用而言是一個可預測狀態的容器。換言之,它是一個應用資料流框架。Redux最主要是用作應用狀態的管理。簡言之,Redux用一個單獨的常量狀態樹(物件)儲存這一整個應用的狀態,這個物件不能直接被改變。當一些資料變化了,一個新的物件就會被建立(使用actions和reducers)。

4.3.3、為什麼要用redux

1、redux的本質,redux要解決的問題就是state的管理
2、實現UI與控制分離,是一種MVC的分層思想
React扮演的是View的角色,Redux則是Controller,至於Model就是Redux Store中儲存的State,不使用redux,專案的耦合性會很大。
3、便於state控制和維護
如果保留元件內部的state,那麼當你在多處呼叫這個元件的時候,無法有效管理state的變化,而使用redux可以讓state的每一次變化都是可以控制的。
下圖說明了React和Redux的狀態流分別是怎麼樣的
React和Redux的狀態流
下圖說明了使用Redux管理狀態為什麼是可預測的
action驅動狀態改變

4.3.4、redux的處理流程

[1]redux要做的事情,就是通過action去控制每一個state的狀態變化,把所有state放到store上,交給reducer去管理,這樣就能確保每一個state的變化是可預測的。
[2]元件內部應該是純淨的,任何狀態的變化都需要dispatch一個action去更新state,然後重新渲染更新的部分,並不會重新渲染所有的View。
react-redux互動流程圖

4.3.5、redux中一些重要概念

1、Action
Action是把資料從應用(譯者注:這裡之所以不叫 view 是因為這些資料有可能是伺服器響應,使用者輸入或其它非 view 的資料 )傳到 store 的有效載荷。它是 store 資料的唯一來源。一般來說你會通過store.dispatch()將 action 傳到 store。
2、Store
前面我們知道使用action來描述“發生了什麼”,和使用reducers來根據 action 更新 state 的用法。而Store就是把它們聯絡到一起的物件。
3、Provider
Provider是一個普通元件,可以作為頂層app的分發點,它只需要store屬性就可以了。它會將state分發給所有被connect的元件,不管它在哪裡,被巢狀多少層。
Provider乾的事:接收store,並將store傳到子元件中,當store發生變化時,更新store;所以子元件具有store的dispatch方法。
4、connect
connect是一個方法,我們可以通過export default connect(select)(App) 繫結Redux與React,連線 React 元件與 Redux store。
connect乾的事:定義了一個新的元件Connect,經過一系列的merge後,將各種值掛載props上傳遞到原元件。 Connect元件會儲存state狀態,同時監聽Redux Store的變化,從而觸發原元件的更新。
mapStateToProps :mapStateToProps是一個函式。它的作用就是像它的名字那樣,建立一個從(外部的)state物件到(UI 元件的)props物件的對映關係。作為函式,mapStateToProps執行後應該返回一個物件,裡面的每一個鍵值對就是一個對映。請看下面的例子:

export default connect((state) => {
return {
        mainStore: state.mainStore,
    }
})(PageMain);

mapStateToProps會訂閱 Store,每當state更新的時候,就會自動執行,重新計算 UI 元件的引數,從而觸發 UI 元件的重新渲染。
connect方法可以省略mapStateToProps引數,那樣的話,UI 元件就不會訂閱Store,就是說 Store 的更新不會引起 UI 元件的更新。