5) React Native 相關(guān)JS和React基礎(chǔ)

對于沒JS以及React開發(fā)經(jīng)驗(yàn)的人(比如我T_T),感覺還是需要簡單了解下React Native所應(yīng)用到的最基礎(chǔ)的JS及React知識,才能更近一步地進(jìn)行React Native開發(fā)。

JS_React(圖片自p哈哈哈).png

一、JavaScript基礎(chǔ)

1. 什么是JavaScript?

JS是一個(gè)輕量級的,解釋型的講函數(shù)視為一級公民的程序設(shè)計(jì)語言。他是一種基于原型的多范式動態(tài)腳本語言,支持面向?qū)ο螅钍骄幊毯秃瘮?shù)式編程。

JavaScript的標(biāo)準(zhǔn)是 ECMAScript,React Native的語法是基于ECMAScript 6,簡稱ES6.(下面文章內(nèi)容主要是以ES6為標(biāo)準(zhǔn)介紹)

JS的組成:
a) 核心(ECMAScript):描述了該語言的語法和基本對象。擔(dān)當(dāng)?shù)氖且粋€(gè)翻譯的角色;是一個(gè)解釋器;幫助計(jì)算機(jī)來讀懂我們寫的程序;實(shí)現(xiàn)加減乘除, 定義變量;
b) 文檔對象模型(DOM):描述了處理網(wǎng)頁內(nèi)容的方法和接口。文檔指的就是網(wǎng)頁;把網(wǎng)頁變成一個(gè)JS可以操作的對象;給了JS可以操作頁面元素的能力;
c) 瀏覽器對象模型(BOM):描述了與瀏覽器進(jìn)行交互的方法和接口。給了JS操作瀏覽器的能力;

2. JS的基礎(chǔ)知識

1) 聲明變量,常量
  • var 聲明變量,可以在聲明的時(shí)候初始化為一個(gè)值
  • let 聲明塊范圍局部變量,可以在聲明的時(shí)候初始化一個(gè)值
  • const 聲明一個(gè)只讀常量(和let一樣只在塊級作用域之內(nèi)有效)

命名規(guī)范:命名要以數(shù)字字母下劃線開頭 。
注意點(diǎn):

  1. JS是大小寫敏感的
  2. JS是一個(gè)動態(tài)類型語言(dynamically typed language)中,所以變量不需聲明類型,必要的時(shí)候自動轉(zhuǎn)換

舉例:

var mainText = "稀飯"
var subText = "歡迎閱讀"

調(diào)用和顯示(在render函數(shù)中返回):

return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          {mainText}
        </Text>
        <Text  style={[styles.instructions, {backgroundColor: 'green'}]}>
          {subText}
        </Text>
      </View>
    );

常量可以看到index.ios.js文件最下面有類似,styles就是一個(gè)常量:

const styles = StyleSheet.create({....

常量在聲明的時(shí)候,必須初始化。

在JS中,{} 大括號,表示定義一個(gè)對象,大部分情況下要有成對的屬性和值,或是函數(shù)。
1){mainText}代表一個(gè)JS對象,在<Text>顯示mainText的內(nèi)容而不是現(xiàn)實(shí)'mainText'字符串。
2)style={[styles.instructions, {backgroundColor: 'green'}]}中,{[...]}為一個(gè)數(shù)組對象,styles.instructions和{backgroundColor: 'green'}均表示一個(gè)JS對象,為數(shù)組元素。

2) 流程控制
  • if,else
  • switch
  • for
  • while
  • break
  • continue
    這個(gè)各個(gè)語言大同小異, 特殊點(diǎn):JS中的Switch Case中可以是String
3) 注釋
// 這是一個(gè)單行注釋.

/* 這是一個(gè)多行注釋。
   它可以是任意長度,
   你可以在這里隨便寫什么。 
*/
4) Promises

** JS本身是單線程的語言,它要實(shí)現(xiàn)異步都是通過回調(diào)函數(shù)來實(shí)現(xiàn)的。**
從ES6開始,JS中引入了Promises來處理異步和延遲操作,在React Native的網(wǎng)絡(luò)請求中是很常見的。
Promises交互主要通過它的then方法,then方法接受一個(gè)回調(diào)函數(shù),這個(gè)回調(diào)函數(shù)接受執(zhí)行成功的返回值或執(zhí)行失敗的錯(cuò)誤原因,錯(cuò)誤原因一般是Error對象。需要注意的是,then方法執(zhí)行的返回值是一個(gè)Promise對象,而then方法接受的回調(diào)函數(shù)的返回值則可以是任意的JavaScript對象,包括Promises。

例子(簡單get網(wǎng)絡(luò)請求):

fetch(url)
    .then((response) => response.text())
    .then((responseText) => {
      callback1(JSON.parse(responseText));
    })
    .catch((error) => {
      callback2(JSON.parse(error));
    })
    .done();
  }

一個(gè)promise有以下幾種狀態(tài):

  • pending,最初的狀態(tài)
  • fulfilled,執(zhí)行成功
  • rejected,執(zhí)行出錯(cuò)
  • settled,執(zhí)行結(jié)束了,失敗(rejected)或者成功(fulfilled)

控制圖如下:


控制圖.png

目前對promise的理解還停留在網(wǎng)絡(luò)請求以及在與原生交互的應(yīng)用上。
這里有一篇推薦的文章,寫得像小說一樣去理解promise,讀讀也不錯(cuò):
ES6 JavaScript Promise的感性認(rèn)知
也有正常些的文章:初識JavaScript Promises

5) 函數(shù)

函數(shù)的定義如下,由function關(guān)鍵字聲明,在()添加輸入,輸入不需要聲明類型

//在class外,這樣的方法是定義在全局的
function globalFunction(input){
    console.log(input);
}

//在class內(nèi),當(dāng)在類中定義的時(shí)候,不需要funciton關(guān)鍵字
//通過this.functionName來訪問
var mainText = "點(diǎn)擊屏幕任意位置"
class JSReactBasics extends Component {
  render() {
    return (
      <TouchableHighlight
        onPress={() => this.backgorundClicked()}
        underlayColor = '#ddd'
        style = {styles.container}
        >
        <Text style={styles.welcome}>{mainText}</Text>
      </TouchableHighlight>
    );
  }
  backgorundClicked(){
    console.log("類中的方法");
  }
}
6) 箭頭函數(shù)(Arrow functions)

箭頭函數(shù)=>無疑是ES6中最受關(guān)注的一個(gè)新特性了,通過它可以簡寫 function 函數(shù)表達(dá)式,你也可以在各種提及箭頭函數(shù)的地方看到這樣的觀點(diǎn)——“=> 就是一個(gè)新的 function”。

onPress={() => this.backgorundClicked()}

這里onPress是一個(gè)函數(shù)類型(在JS中,函數(shù)本身也是一種類型)。這其實(shí)是JS中的箭頭函數(shù),他提供了一種更簡潔的函數(shù)表達(dá)方式。

var a2 = a.map(function(s){ return s.length });
var a3 = a.map( (s) => s.length );
console.log(a2);
console.log(a3);

可以看到兩個(gè)log的內(nèi)容是一樣的。(s)用來描述參數(shù),=>后的表示方法的執(zhí)行體。學(xué)過Swift的童鞋,會發(fā)現(xiàn)和Swift的必包很像。

注意:
this,在一個(gè)類中的不同地方,比如閉包函數(shù)中,this的指向并不都是這個(gè)類的實(shí)例。(經(jīng)常出問題的地方,需不需要.bind(this))
普通函數(shù).bind(this) 來把內(nèi)部函數(shù)中的 this 綁定到了外部函數(shù)去。
箭頭函數(shù)里的this還是原來的this,不需要額外綁定。

7) 模板字符串

ES6 中引進(jìn)的一種新型的字符串字面量語法 - 模板字符串。書面上來解釋,模板字符串是一種能在字符串文本中內(nèi)嵌表示式的字符串字面量。簡單來講,就是增加了變量功能的字符串。

模板字符串使用反引號`來代替普通字符串中的用雙引號和單引號。模板字符串可以包含特定語法(${expression})的占位符。占位符中的表達(dá)式和周圍的文本會一起傳遞給一個(gè)默認(rèn)函數(shù),該函數(shù)負(fù)責(zé)將所有的部分連接起來。

var name = '丁香醫(yī)生';
var desc = '丁香醫(yī)生是面向大眾的科普性健康類網(wǎng)站';

//Before ES6 字符串拼接
var html = function(name, desc){
    var tpl = '公司名:' + name + '\n'+
            '簡介:'+ desc;
    return tpl;
}

//ES6 字符串拼接
var html = `公司名:${name}   
簡介:${desc}`;

3. 數(shù)據(jù)結(jié)構(gòu)和類型

1) 基本數(shù)據(jù)類型:
  • Boolean,布爾值,true或者false

  • null,一個(gè)表明null的特殊關(guān)鍵字,注意JS中大小寫敏感,null和NULL是完全不同的東西

  • undefined.變量未定義的屬性 (兩種情況:1是真的沒有定義, 2是雖然定義了,但沒有賦值;)

  • Number,數(shù)字

  • String,字符串

  • **Symbol **,ES6中新增的,唯一不可變的

  • Object 對象是一個(gè)復(fù)合類型,它是由一組基本類型組成的;如:div,它是一個(gè)對象,它有id,width等特性,它的id是string的,width是number的;

以下值在JS中是會識別為false:

  • false
  • undefined
  • null
  • 0
  • NaN
  • 空字符串 ("")
2) 變量類型轉(zhuǎn)換

檢測變量類型: typeof()

  1. parseInt():從字符串中提取數(shù)字;
  2. NaN:not a number;
    i. NaN 和任何數(shù)計(jì)算 都是NaN;
    ii. NaN 不與任何值相等,包括它自身;要比較需要使用方法isNaN();
  3. 顯性類型轉(zhuǎn)換:
    i. parseInt()/ parseFloat();
    ii. NaN 的意義和檢測:
    意義:not a number;
    檢測:isNaN();
  4. 隱式類型轉(zhuǎn)換:
    i. "==" ,就是隱式轉(zhuǎn)換,它會先把兩邊的東西轉(zhuǎn)成一樣的類型,然后再進(jìn)行比較;
    ii. 減法、乘法、除法 也會進(jìn)行自發(fā)的隱式轉(zhuǎn)換;只有加號不可以;
3) 數(shù)組

可以由以下三種方式創(chuàng)建數(shù)組,訪問數(shù)組的方式還是通過角標(biāo)來訪訪問:

var a = ["1","2","3","4"];
var b = new Array("1","2","3","4")
var c = Array("1","2","3","4")
console.log(a[1]);

數(shù)組有一些方便的方法,例如合并,排序,檢索等,可以在MDN上找到

4) 字典Maps(相當(dāng)于iOS中的NSDictionary)
var map = {"key1":"value1","key2":"value2"}
var map = {"key1":"value1","key2":"value2"}
map["key4"] = "value4"
console.log(map["key1"])
console.log(map["key4"])
5) 對象

JS中的對象的屬性可以不先聲明,而在運(yùn)行時(shí)候動態(tài)添加,例如:

var obj = new Object()
obj.name = "1234"
console.log(obj.name);

所以,在React Native中,寫代碼的時(shí)候,存儲數(shù)據(jù)直接this.propertyName =即可

4. JavaScript是基于原型的面對象語言

理解這一點(diǎn),對使用JS開發(fā)還是比較重要的。
像Java,Objective C,C++都是基于類的面向?qū)ο笳Z言。
面向?qū)ο笳Z言有兩個(gè):

  1. 基于類的面向?qū)ο笳Z言主要有兩個(gè)概念
  • 類(class),定義了一組具有某一類特征的事務(wù)。類是抽象的,比如鳥類
  • 實(shí)例(instance),實(shí)體是類的實(shí)體話提現(xiàn),比如一只鳥
  1. 基于原型的面向?qū)ο?/strong>
  • 基于原型的面向?qū)ο笳Z言并不存在這種區(qū)別,基于原型的面向?qū)ο笳Z言所有的都是對象。基于原型的面向?qū)ο笳Z言有一個(gè)概念叫做原型對象,古代有一種東西叫做活字印刷術(shù),那一個(gè)個(gè)字的模版就是這里的原型對象。

React Native引入了基于類的面向?qū)ο缶幊谈拍睿@個(gè)在后面講解React基礎(chǔ)的時(shí)候來介紹

通過比較Java和JS可以了解二者的區(qū)分

|基于類的(Java)|基于原型的(JavaScript)|
| : ------: | : ------: |
|類和實(shí)例是不同的事物。|所有對象均為實(shí)例。|
|通過類定義來定義類;通過構(gòu)造器方法來實(shí)例化類。|通過構(gòu)造器函數(shù)來定義和創(chuàng)建一組對象。|
|通過 new 操作符創(chuàng)建單個(gè)對象。|相同。|
|通過類定義來定義現(xiàn)存類的子類,從而構(gòu)建對象的層級結(jié)構(gòu)。|指定一個(gè)對象作為原型并且與構(gòu)造函數(shù)一起構(gòu)建對象的層級結(jié)構(gòu)|
|遵循原型鏈繼承屬性。|構(gòu)造器函數(shù)或原型指定初始的屬性集。允許動態(tài)地向單個(gè)的對象或者整個(gè)對象集中添加或移除屬性。|

二、React基礎(chǔ)

1. 什么是React?

A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES(一個(gè)JavaScript的用來創(chuàng)建界面的庫)

通過名字就可以看出來,ReactNative是基于React來寫的支持編寫原生App的框架。

2. React的基礎(chǔ)知識

1) React

React是整個(gè)React框架的入口

2) React.Component

Component是React類的基類,類似于iOS的UIView和Android的View,React和React native都定義了很多方便的子類來給開發(fā)者使用。

3) React.createClass

創(chuàng)建一個(gè)Component

4) Component 相關(guān)對象方法

render
調(diào)用React.createClass或者讓一個(gè)類繼承自class JSReactBasics extends Component都是需要提供render函數(shù)的。這個(gè)函數(shù)返回一個(gè)根的視圖,用來渲染實(shí)際的Component可視部分,如下:

render() 中 返回的的 JSX 模板需要一個(gè)根元素包裹起來

render() {
    return (
      <TouchableHighlight
        onPress={() => this.backgorundClicked()}
        underlayColor = '#ddd'
        style = {styles.container}
        >
        <Text style={styles.welcome}>{mainText}</Text>
      </TouchableHighlight>
    );
  }

getInitialState()
在Component被加載之前調(diào)用一次,這個(gè)方法的返回值回被設(shè)置為this.state

Tips:這個(gè)方法只能在用React.createClass創(chuàng)建的時(shí)候使用,例如,在我們示例代碼中,加入一個(gè)方法

getInitialState(){
    return {key:"value"}
  }

getDefaultProps()
在Class 創(chuàng)建的時(shí)候,調(diào)用一次,這個(gè)方法在調(diào)用的時(shí)候,任何實(shí)例還沒有被創(chuàng)建。還有一點(diǎn)要注意,這個(gè)方法返回的任何Object 對象,在各個(gè)實(shí)例中是共享的,而不是每個(gè)實(shí)例一個(gè)copy。

5) statics

statics對象,用來定義Components可以調(diào)用的靜態(tài)方法,例如

var MyComponent = React.createClass({
  statics: {
    customMethod: function(foo) {
      return foo === 'bar';
    }
  },
  render: function() {
  }
});

MyComponent.customMethod('bar');  // true

3. 組件的生命周期

個(gè)人覺得React Native最核心的概念就是組件了,因此一定需要去理清組件的運(yùn)作方式,即組件的生命周期,這樣才能更合理地去實(shí)際應(yīng)用。
因?yàn)榻M件的生命周期網(wǎng)上有好多好多類似的文章都有詳細(xì)的描述,這篇文章的內(nèi)容又已經(jīng)太多了,所以這里留下一圖一表供簡單的理解,會在下一篇文章結(jié)合ES6對組件的生命周期進(jìn)行詳細(xì)描述。

組件的生命周期.png

|生命周期 |調(diào)用次數(shù) |能否使用 setSate() |
|: ------:|:------:|:------:|
|defaultProps / getDefaultProps| 1(全局調(diào)用一次) | 否
|constructor / getInitialState |1 |否
|componentWillMount |1 |
|render |>=1 |否
|componentDidMount |1 |
|componentWillReceiveProps |>=0 |
|shouldComponentUpdate |>=0 |否
|componentWillUpdate |>=0 |否
|componentDidUpdate |>=0 |否
|componentWillUnmount |1 |否


本文極大的參考了另外一篇文章的篇寫,自己也添加了自己的見解和進(jìn)一步的整理,感謝原文:http://blog.csdn.net/hello_hwc/article/details/51199384

這篇文章整理了下自從入門React Native之后所遇到的關(guān)于JS和React基礎(chǔ)的知識點(diǎn),還記得一開始的時(shí)候是懵噠到{{}}為啥要這樣做都完全不知道,函數(shù)也不會調(diào)用,總是有this為空,該bind的時(shí)候沒bind,不該的時(shí)候又bind了。。。等等一大堆問題,所以還是覺得先理解好一些最基本的東西才能進(jìn)行更好的開發(fā)。

正在寫React Native的學(xué)習(xí)教程ing,是一邊研究一邊編寫的,已有的成果如下:
1) React Native 簡介與入門
2) React Native 環(huán)境搭建和創(chuàng)建項(xiàng)目(Mac)
3) React Native 開發(fā)之IDE
4) React Native 入門項(xiàng)目與解析

  1. React Native 相關(guān)JS和React基礎(chǔ)
    6) React Native 組件生命周期(ES6)
    7) React Native 集成到原生項(xiàng)目(iOS)
    8) React Native 與原生之間的通信(iOS)
    9) React Native 封裝原生UI組件(iOS)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,784評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,746評論 2 370

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