React Native 快速入門

React Native (簡(jiǎn)稱RN)是Facebook于2015年4月開源的跨平臺(tái)移動(dòng)應(yīng)用開發(fā)框架侄柔,是Facebook早先開源的UI框架 React 在原生移動(dòng)應(yīng)用平臺(tái)的衍生產(chǎn)物恨憎,目前支持iOS和安卓兩大平臺(tái)。RN使用Javascript語言切诀,類似于HTML的JSX,以及CSS來開發(fā)移動(dòng)應(yīng)用少孝,因此熟悉Web前端開發(fā)的技術(shù)人員只需很少的學(xué)習(xí)就可以進(jìn)入移動(dòng)應(yīng)用開發(fā)領(lǐng)域饿序。

一、從 ES6 開始

  1. const、let 關(guān)鍵字

    • let:眾所周知 JavaScript 中變量默認(rèn)是全局的皂林,只存在函數(shù)級(jí)作用域朗鸠。ES6中提出 let 關(guān)鍵字,使JavaScript 也有了塊級(jí)作用域式撼。

    • const:用來定義常量童社,一旦定以后不可修改,但是可以修改屬性著隆。

      const MYNAME = {foo: 'Ginger'};
      MYNAME.foo = 'Zoe';
      
  2. 函數(shù)

    • 箭頭函數(shù)
      可以看做是一種語法糖,箭頭函數(shù)永遠(yuǎn)是匿名的

      let add = (a, b) => {return a + b;}
      // 當(dāng)后面是表達(dá)式的時(shí)候呀癣,還可以簡(jiǎn)寫成
      let add = (a, b) => a + b;
      // 等同于
      let add = function(a, b){
        return a + b;
      }
      // 在回調(diào)函數(shù)中的應(yīng)用
      let numbers = [1, 2, 3];
      let doubleNumbers = numbers.map((number) => number * 2); // [2, 4, 6]
      
    • this 在箭頭函數(shù)中的使用
      在對(duì)象方法的嵌套函數(shù)中美浦,this 會(huì)指向 global。

      let age = 2;
      let kitty = {
        age: 1,
        grow: function() {
          setTimeout(function() {
            console.log(++this.age);
          }, 100);
        }
      }
      kitty.grow(); // 3
      
      // 一般的解決方法
      let kitty = {
        age: 1,
        grow: function() {
          setTimeout(function() {
            console.log(++this.age);
          }.bind(this), 100);
        }
      }
      // 或者
      let kitty = {
        age: 1,
        grow: function() {
          const self = this;
          setTimeout(function() {
            console.log(++self.age);
          }.bind(this), 100);
        }
      }
      
      // 有了箭頭函數(shù)這個(gè)問題就可以輕松解決了
      let kitty = {
        age: 1,
        grow: function() {
          setTimeout(() => {
            console.log(++this.age);
          }, 100);
        }
      }
      
    • 默認(rèn)參數(shù)函數(shù)

      function desc(name = 'Ginger', age = 18){
        return name + ' is ' + age + ' years old';
      }
      desc();
      //Ginger is 18 years old
      
    • Rest 參數(shù)
      當(dāng)一個(gè)函數(shù)的最后一個(gè)參數(shù)有“…”這樣的前綴项栏,它就會(huì)變成一個(gè)參數(shù)的數(shù)組浦辨。

      function test(...args){
        console.log(args);
      }
      
      test(1, 2, 3);
      //[1, 2, 3]
      
      function test2(name, ...args){
        console.log(args);
      }
      
      test2('Ginger', 2, 3);
      //[2, 3]
      

      ?

  3. 展開操作符(“…”)

    允許一個(gè)表達(dá)式在某處展開,在存在多個(gè)參數(shù)(用于函數(shù)調(diào)用)沼沈、多個(gè)元素(用于數(shù)組字面量)或者多個(gè)變量(用于結(jié)構(gòu)賦值)的地方就會(huì)出現(xiàn)這種情況流酬。

    • 用于函數(shù)調(diào)用

      // 之前,想讓函數(shù)把一個(gè)數(shù)組作為依次作為參數(shù)調(diào)用方法如下
      function test(x, y, z) { };
      var args = [1, 2, 3];
      test.apply(null, args);
      
      // 有了 ES6 的展開運(yùn)算符之后
      function test(x, y, z) { };
      let args = [1, 2, 3];
      test(...args);
      
    • 用于數(shù)組字面量
      在之前的版本中列另,想要?jiǎng)?chuàng)建含某些元素的新數(shù)組芽腾,常使用 splice、concat页衙、push.

      var arr1 = [1, 2, 3];
      var arr2 = [4, 5, 6];
      var arr3 = arr1.concat(arr2);
      
      // 使用 ES6 之后
      let arr1 = [1, 2, 3];
      let arr2 = [4, 5, 6];
      let arr3 = [...arr1, ...arr2];
      
    • 對(duì)象的展開運(yùn)算符

      let mike = {name: 'mike', age: 50};
      mike = {...mike, sex: 'male'};
      console.log(mike);
      // {name: 'mike', age: 50, sex: 'male'}
      
  4. 模板字符串(注意不是',是`)
    字符串拼接總是令人很不爽的一件事情摊滔,但是在 ES6 來臨的時(shí)代,這個(gè)痛處也被治愈了店乐。

    // 之前
    var name = 'Ginger';
    var a = 'My name is ' + Ginger + '!'
    // 多行
    var langStory = 'This is a long story,'
          + 'this is a long story,'
          + 'this is a long story.';
    // 有了 ES6 之后
    let name = 'Ginger';
    let a = `My name is ${name} !`;
    let longStory = `This is a long story,
                 this is a long story,
                 this is a long story`;
    
  5. 解構(gòu)賦值

    • 解構(gòu)數(shù)組

       let foo = ['one', 'two', 'three'];
       let [one, two, three] = foo;
      
       console.log(`${one}, ${two}, ${three}`);
       // one, two, three
      
    • 解構(gòu)對(duì)象

         let person = {name: 'Ginger', age: 18};
         let {name, age} = person;
      
         console.log(`${name}, ${age}`);
         // Ginger, 18
      

  6. 提供了 class 這個(gè)語法糖艰躺。讓開發(fā)者可以模仿其他語言類的聲明方式。只是原型鏈方式的一種語法糖眨八。

       class Animal {
         // 構(gòu)造函數(shù)
         constructor (name, age) {
           this.name = name;
           this.age = age;
         }
         shout() {
           return `${name}, ${age}`;
         }
         // 靜態(tài)方法
         static foo() {
           return 'here is a static method';
         }
       }
    
       const cow = new Animal('betty', 2);
       cow.shout(); // betty, 2
    
       Animal.foo(); // here is a static method
    
       class Dog extends Animal {
         constructor(name, age = 2, color = 'black') {
           // 在構(gòu)造函數(shù)中可以直接調(diào)用 spuer 方法
           super(name, age);
           this.color = color;
         }
         shout(){
           // 非構(gòu)造函數(shù)中不能直接調(diào)用 super 方法
           return `${name}, ${age}, ${color}`;
         }
       }
    

    ?

  7. 模塊
    在 ES6 之前腺兴,JavaScript 并沒有對(duì)模塊做出任何定義,于是先驅(qū)者們創(chuàng)造了各種各樣的規(guī)范來完成這個(gè)任務(wù)廉侧。比如 Require.js页响,CommonJS,browerify 等等伏穆。
    使用 import export 關(guān)鍵字來完成模塊的導(dǎo)入和導(dǎo)出拘泞。
    還可以使用 default 關(guān)鍵字來默認(rèn)導(dǎo)出。

二枕扫、再說說 React

特點(diǎn):1. 組件化陪腌;2. JSX;3. 虛擬 DOM;

  1. JSX

    • JSX 不是必須的诗鸭。類似一種語法糖染簇。把標(biāo)簽型的寫法轉(zhuǎn)化成 React 提供的一個(gè)用來創(chuàng)建 ReactElement 的方法。

      let app = <h1 title = "My title">this is my title</h1>
      // jsx轉(zhuǎn)換后的結(jié)果
      let app = React.createElement('h1', {title: 'my title', 'this is my title'});
      
    • HTML 標(biāo)簽與 React 組件
      HTML 標(biāo)簽第一個(gè)字母用小寫表示强岸。
      React 組件第一個(gè)字母用大寫表示锻弓。
      JSX 語法使用第一個(gè)字母大小寫來區(qū)分是一個(gè)普通的 HTML 標(biāo)簽還是一個(gè) React 組件。

    • JavaScript 表達(dá)式
      當(dāng)遇到{}這個(gè)表達(dá)式的情況下蝌箍,里面的代碼會(huì)被仿作 JavaScript 代碼處理青灼。
      當(dāng)省略一個(gè)屬性值的時(shí)候,JSX會(huì)自動(dòng)把它的值認(rèn)為是 true妓盲。

    • 注釋
      JSX 注釋沿用 JavaScript 的方法杂拨,需要注意的是,在子組件的位置需要用{}括起來悯衬。

      let component = (
        <div>
         {/*這里是一個(gè)注釋弹沽!*/}
         <Headline />
        </div>
      );
      
    • JSX 屬性擴(kuò)散

      let props = {
        name: 'Ginger',
        age: 18
      }
      
      // 用這種方式可以將 name,age 全部載入進(jìn)來
      let component = <Profile {...props} />
      
      // 值得注意的是筋粗,越靠后的屬性會(huì)覆蓋前面的屬性
      let component = <Profile {...props} name='Zoe' />
      
  2. React 的生命周期

    實(shí)例化

    首次實(shí)例化

    • getDefaultProps
    • getInitialState
    • componentWillMount
    • render
    • componentDidMount

    實(shí)例化完成后的更新

    • getInitialState
    • componentWillMount
    • render
    • componentDidMount
    存在期

    組件已存在時(shí)的狀態(tài)改變

    • componentWillReceiveProps
    • shouldComponentUpdate
    • componentWillUpdate
    • render
    • componentDidUpdate
    銷毀&清理期
    • componentWillUnmount
    說明

    生命周期共提供了10個(gè)不同的API策橘。

    1.getDefaultProps

    作用于組件類,只調(diào)用一次娜亿,返回對(duì)象用于設(shè)置默認(rèn)的props丽已,對(duì)于引用值,會(huì)在實(shí)例中共享暇唾。

    2.getInitialState

    作用于組件的實(shí)例促脉,在實(shí)例創(chuàng)建時(shí)調(diào)用一次,用于初始化每個(gè)實(shí)例的state策州,此時(shí)可以訪問this.props瘸味。

    3.componentWillMount

    在完成首次渲染之前調(diào)用,此時(shí)仍可以修改組件的state够挂。

    4.render

    必選的方法旁仿,創(chuàng)建虛擬DOM,該方法具有特殊的規(guī)則:

    • 只能通過this.propsthis.state訪問數(shù)據(jù)
    • 可以返回null孽糖、false或任何React組件
    • 只能出現(xiàn)一個(gè)頂級(jí)組件(不能返回?cái)?shù)組)
    • 不能改變組件的狀態(tài)
    • 不能修改DOM的輸出
    5.componentDidMount

    真實(shí)的DOM被渲染出來后調(diào)用枯冈,在該方法中可通過this.getDOMNode()訪問到真實(shí)的DOM元素。此時(shí)已可以使用其他類庫來操作這個(gè)DOM办悟。比如 AJAX 請(qǐng)求可以放在這里尘奏。

    在服務(wù)端中,該方法不會(huì)被調(diào)用病蛉。

    6.componentWillReceiveProps

    組件接收到新的props時(shí)調(diào)用炫加,并將其作為參數(shù)nextProps使用瑰煎,此時(shí)可以更改組件propsstate

        componentWillReceiveProps: function(nextProps) {
            if (nextProps.bool) {
                this.setState({
                    bool: true
                });
            }
        }
    
    7.shouldComponentUpdate

    組件是否應(yīng)當(dāng)渲染新的propsstate俗孝,返回false表示跳過后續(xù)的生命周期方法酒甸,通常不需要使用以避免出現(xiàn)bug。在出現(xiàn)應(yīng)用的瓶頸時(shí)赋铝,可通過該方法進(jìn)行適當(dāng)?shù)膬?yōu)化插勤。

    在首次渲染期間或者調(diào)用了forceUpdate方法后,該方法不會(huì)被調(diào)用

    8.componentWillUpdate

    接收到新的props或者state后革骨,進(jìn)行渲染之前調(diào)用农尖,此時(shí)不允許更新propsstate

    9.componentDidUpdate

    完成渲染新的props或者state后調(diào)用苛蒲,此時(shí)可以訪問到新的DOM元素卤橄。不能再該狀態(tài)下 setState 等,會(huì)造成組件死循環(huán)臂外。

    10.componentWillUnmount

    組件被移除之前被調(diào)用,可以用于做一些清理工作喇颁,在componentDidMount方法中添加的所有任務(wù)都需要在該方法中撤銷漏健,比如創(chuàng)建的定時(shí)器或添加的事件監(jiān)聽器。

  3. 組件
    先來一個(gè)簡(jiǎn)單的例子橘霎。

    import React from 'react';
    
    class List extends React.Component {
      // 在 ES6 中不再使用getInitialState而使用constructor
      constructor(props) {
        super(props);
        this.state = ['a', 'b', 'c'];
      }
      
      render(){
        return (...);
      }
    }
    
    • props 屬性
      可以看做是組件的數(shù)據(jù)來源蔫浆。
      要想子組件傳遞數(shù)據(jù)需要通過 props 來完成

    • state 狀態(tài)
      state 是組件內(nèi)部的屬性。
      當(dāng) state 的值發(fā)生改變的時(shí)候姐叁,可以調(diào)用 this.setState 方法讓組件再次調(diào)用 render 方法瓦盛,重新渲染 UI。
      state 中應(yīng)該包含組件的事件回調(diào)函數(shù)可能引發(fā) UI 更新的這類數(shù)據(jù)外潜。

    • 引入組件
      將組件的文件引入原环,再在新的組件中加入已經(jīng)寫好的組件標(biāo)簽。

      import React from 'react';
      import List from './list';
      
      class Profile extends React.Component {
        // 在 ES6 中不再使用getInitialState而使用constructor
        constructor(props) {
          super(props);
        }
        
        render(){
          return (
            <List />
          );
        }
      }
      

三处窥、讓我們開始 React Native 的旅程

  1. 快速開始
    參考網(wǎng)站:http://reactnative.cn/docs/0.41/getting-started.html
    事先搭建好開發(fā)環(huán)境嘱吗。快速開始:react-native init HelloRN
    進(jìn)入這個(gè) HelloRN 文件夾后滔驾,里面有兩個(gè)入口文件: index.ios.js index.android.js谒麦,修改入口文件內(nèi)容刷新模擬器,即可看到你寫的內(nèi)容~

  2. flexbox 布局
    我們?cè)赗eact Native中使用flexbox規(guī)則來指定某個(gè)組件的子元素的布局哆致。Flexbox可以在不同屏幕尺寸上提供一致的布局結(jié)構(gòu)绕德。
    一般來說,使用flexDirection摊阀、alignItemsjustifyContent三個(gè)樣式屬性就已經(jīng)能滿足大多數(shù)布局需求耻蛇。
    摘自網(wǎng)上總結(jié)的很好的 flex 布局口訣圖踪蹬。(http://weibo.com/1712131295/CoRnElNkZ?ref=collection&type=comment#_rnd1488247287265

    flex1.jpg

    flex2.jpg

    flex3.jpg

    flex4.jpg

    flex5.jpg

  3. 常用組件介紹
    入口文件說明

    import React, { Component } from 'react';
    import {
      AppRegistry,
      StyleSheet,
      Text,
      View
    } from 'react-native'; // 將使用到的 react-native 組件引入
    
    export default class reactNative extends Component {
      render() {
        return (
          //  View 組件相當(dāng)于 html 的 div〕巧ィ可以視作一個(gè)包裹內(nèi)容的容器延曙。
          <View style={styles.container}>
             // 所有的文字內(nèi)容都需要被包裹在 Text 標(biāo)簽中
            <Text style={styles.welcome}>
              Welcome to React Native!
            </Text>
             // 若要直接在組件中寫入樣式 <Text style={{textAlign: 'center'}}>。注意是 {{}}
            <Text style={styles.instructions}>
              To get started, edit index.ios.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>
        );
      }
    }
    
    // StyleSheet提供了一種類似CSS樣式表的抽象亡哄。RN 中樣式使用駝峰格式枝缔。
    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('reactNative', () => reactNative);
    // AppRegistry是JS運(yùn)行所有React Native應(yīng)用的入口。應(yīng)用的根組件應(yīng)當(dāng)通過AppRegistry.registerComponent方法注冊(cè)自己蚊惯,然后原生系統(tǒng)才可以加載應(yīng)用的代碼包并且在啟動(dòng)完成之后通過調(diào)用AppRegistry.runApplication來真正運(yùn)行應(yīng)用愿卸。
    
    • View
      類似于 html 中的 div,盒子布局截型,將內(nèi)容包裹在里面趴荸。

    • Text
      所有的文字都必須要放在 Text 標(biāo)簽中。

    • Image

    renderImages() {
      return (
        <View>
          // 本地模式
          <Image
            style={styles.icon}
            source={require('./icon.png')}
          />
          // 使用網(wǎng)絡(luò)資源
          <Image
            style={styles.logo}
            source={{uri: 'http://facebook.github.io/react/img/logo_og.png'}}
          />
        </View>
      );
    }
    

    ? 至此宦焦,關(guān)于 React Native 的基礎(chǔ)說明完成发钝。趕快開始在 index.ios.js 中涂涂畫畫吧~

  4. 其他常用組件

    • NavigatorIOS
      該組件本質(zhì)上是對(duì) UIKit navigation 的包裝。也就是說波闹,使用 NavigatorIOS 進(jìn)行路由切換酝豪,實(shí)質(zhì)上是調(diào)用了UIKit的navigation。


      navigation.jpeg
    • TextInput
      通過鍵盤將文本輸入到 app 的組件精堕。

    • Touchable
      RN 沒有像 web 開發(fā)那樣可以個(gè)元素綁定 click 時(shí)間孵淘。Text 組件中可以使用 onPress 事件綁定觸摸點(diǎn)擊事件。為了使其他組件也可以被點(diǎn)擊歹篓,提供了3個(gè)組件來做這個(gè)事情瘫证。這3個(gè)組件被稱為“Touchable類組件”。

    • TarBarIOS
      為切換不同頁面


      TarBar.jpeg
    • WebView

趕快動(dòng)手試試這些組件吧~

參考內(nèi)容:
http://reactnative.cn/docs/0.41/getting-started.html
《React 全椬椋》
《React Native 入門與實(shí)戰(zhàn)》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末背捌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子重窟,更是在濱河造成了極大的恐慌载萌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,640評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巡扇,死亡現(xiàn)場(chǎng)離奇詭異扭仁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)厅翔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門乖坠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人刀闷,你說我怎么就攤上這事熊泵⊙銮ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵顽分,是天一觀的道長徐许。 經(jīng)常有香客問我,道長卒蘸,這世上最難降的妖魔是什么雌隅? 我笑而不...
    開封第一講書人閱讀 58,755評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮缸沃,結(jié)果婚禮上恰起,老公的妹妹穿的比我還像新娘。我一直安慰自己趾牧,他們只是感情好检盼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著翘单,像睡著了一般吨枉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哄芜,一...
    開封第一講書人閱讀 51,610評(píng)論 1 305
  • 那天东羹,我揣著相機(jī)與錄音,去河邊找鬼忠烛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛权逗,可吹牛的內(nèi)容都是我干的美尸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,352評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼斟薇,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼师坎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起堪滨,我...
    開封第一講書人閱讀 39,257評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤胯陋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后袱箱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體遏乔,經(jīng)...
    沈念sama閱讀 45,717評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評(píng)論 3 336
  • 正文 我和宋清朗相戀三年发笔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盟萨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,021評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡了讨,死狀恐怖捻激,靈堂內(nèi)的尸體忽然破棺而出制轰,到底是詐尸還是另有隱情,我是刑警寧澤胞谭,帶...
    沈念sama閱讀 35,735評(píng)論 5 346
  • 正文 年R本政府宣布垃杖,位于F島的核電站,受9級(jí)特大地震影響丈屹,放射性物質(zhì)發(fā)生泄漏调俘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評(píng)論 3 330
  • 文/蒙蒙 一泉瞻、第九天 我趴在偏房一處隱蔽的房頂上張望脉漏。 院中可真熱鬧,春花似錦袖牙、人聲如沸侧巨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽司忱。三九已至,卻和暖如春畴蹭,著一層夾襖步出監(jiān)牢的瞬間坦仍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評(píng)論 1 270
  • 我被黑心中介騙來泰國打工叨襟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留繁扎,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,224評(píng)論 3 371
  • 正文 我出身青樓糊闽,卻偏偏與公主長得像梳玫,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子右犹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容