一、準(zhǔn)備工作
先安裝React Native,然后初始化一個(gè)示例工程
react-native init JSReactBasics
二、什么是JavaScript?
JS是一個(gè)輕量級(jí)的,解釋型的講函數(shù)視為一級(jí)公民的程序設(shè)計(jì)語言。他是一種基于原型的多范式動(dòng)態(tài)腳本語言,支持面向?qū)ο螅钍骄幊毯秃瘮?shù)式編程。
JavaScript的標(biāo)準(zhǔn)是 ECMAScript,React Native的語法是基于ECMAScript 6,簡(jiǎn)稱ES6.
Tips:Java和JavaScript語法很像,但是用處完全不同,而且也是兩個(gè)幾乎沒關(guān)系的東西
關(guān)于Java和JS的區(qū)分,可以見如下表
三、JS的基礎(chǔ)知識(shí)
1、聲明
var 聲明變量,可以在聲明的時(shí)候初始化為一個(gè)值
let 聲明塊范圍局部變量,可以在聲明的時(shí)候初始化一個(gè)值
const 聲明一個(gè)只讀常量
Tips:JS是大小寫敏感的
2、變量,常量
命名要以數(shù)字字母下劃線開頭
例如,在class ReactJSBasics上添加兩行
var mainText = "來自Leo的博客"
var subText = "歡迎閱讀"
Tips:JS是一個(gè)動(dòng)態(tài)類型語言(dynamically typed language)中,所以變量不需聲明類型,必要的時(shí)候自動(dòng)轉(zhuǎn)換
然后,讓Text來顯示這個(gè)這兩個(gè)變量
return (
<View style={styles.container}>
<Text style={styles.welcome}>
{mainText}
</Text>
<Text style={styles.instructions}>
{subText}
</Text>
</View>
);
然后save,選擇模擬器,Command+R刷新,會(huì)看到截圖如下
常量可以看到index.ios.js文件最下面有類似
const styles = StyleSheet.create({....
就是一個(gè)常量。在聲明的時(shí)候,必須初始化
3、數(shù)據(jù)結(jié)構(gòu)和類型
六種基本的原型數(shù)據(jù)類型
Boolean,布爾值,true或者false
null,一個(gè)表明null的特殊關(guān)鍵字,注意JS中大小寫敏感,null和NULL是完全不同的東西
undefined.變量為定義的屬性
Number,數(shù)字
String,字符串
Symbol ,ES6中新增的,唯一不可變的
以及Object類型
4、流程控制
if,else
switch
for
while
break
continue
這個(gè)各個(gè)語言大同小異,不浪費(fèi)篇幅了,有一點(diǎn)要提一下,JS中的Switch Case中可以是String
有一點(diǎn)要注意,以下值在JS中是會(huì)識(shí)別為false
false
undefined
null
0
NaN
空字符串 ("")
5、注釋
// 這是一個(gè)單行注釋.
/* 這是一個(gè)多行注釋。它可以是任意長(zhǎng)度,你可以在這里隨便寫什么。 */
6、Promises
從ES6開始,JS中引入了Promises來處理異步和延遲操作,在React Native的網(wǎng)絡(luò)請(qǐng)求中是很常見的。
一個(gè)promise有以下幾種狀態(tài)
pending,最初的狀態(tài)
fulfilled,執(zhí)行失敗
rejected,執(zhí)行成功
settled,執(zhí)行結(jié)束了,失敗(rejected)或者成功(fulfilled)
控制圖如下
7、函數(shù)
函數(shù)的定義如下,由function關(guān)鍵字聲明,在()添加輸入,輸入不需要聲明類型
function globalFunction(input){
console.log(input);
}
我們接著上述的工程,添加一個(gè)可點(diǎn)擊的TouchableHighLight
在import中,添加一行
TouchableHighlight
重新定義變量和類的內(nèi)容
var mainText = "點(diǎn)擊屏幕任意位置"
function globalFunction(input){
console.log(input);
}
class JSReactBasics extends Component {
render() {
return (
<TouchableHighlight
onPress={() => globalFunction("輸入")}
underlayColor = '#ddd'
style = {styles.container}
>
<Text style={styles.welcome}>{mainText}</Text>
</TouchableHighlight>
);
}
}
然后,save,command+R刷新,再點(diǎn)擊屏幕任意位置,會(huì)發(fā)現(xiàn)如下log
這樣的方法是定義在全局的,當(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("類中的方法");
}
}
8、箭頭函數(shù)(Arrow functions)
沒接觸過JS的同學(xué)可能會(huì)對(duì)
onPress={() => this.backgorundClicked()
這一行感到很奇怪,其實(shí)這里onPress是一個(gè)函數(shù)類型(在JS中,函數(shù)本身也是一種類型)。這其實(shí)是JS中的箭頭函數(shù),他提供了一種更簡(jiǎn)潔的函數(shù)表達(dá)方式
修改backgorundClicked,為如下內(nèi)容
backgorundClicked(){
var a = [
"Hydrogen",
"Helium",
"Lithium",
"Beryl-lium"
];
var a2 = a.map(function(s){ return s.length });
var a3 = a.map( (s) => s.length );
console.log(a2);
console.log(a3);
}
然后,save,Commnad+R刷新,可以看到兩個(gè)log的內(nèi)容是一樣的。也就是說,(s)用來描述參數(shù),=>后的表示方法的執(zhí)行體。學(xué)過Swift的童鞋,會(huì)發(fā)現(xiàn)和Swift的必包很像。
9、數(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上找到
10、字典Maps
var map = {"key1":"value1","key2":"value2"}
var map = {"key1":"value1","key2":"value2"}
map["key4"] = "value4"
console.log(map["key1"])
console.log(map["key4"])
11、對(duì)象
JS中的對(duì)象的屬性可以不先聲明,而在運(yùn)行時(shí)候動(dòng)態(tài)添加,例如
var obj = new Object()
obj.name = "1234"
console.log(obj.name);
所以,在React Native中,寫代碼的時(shí)候,存儲(chǔ)數(shù)據(jù)直接this.propertyName =即可
四、JavaScript是基于原型的面對(duì)象語言
理解這一點(diǎn),對(duì)使用JS開發(fā)還是比較重要的。
像Java,Objective C,C++都是基于類的面向?qū)ο笳Z言,面向?qū)ο笳Z言有兩個(gè),基于類的面向?qū)ο笳Z言主要有兩個(gè)概念:
1、類(class),定義了一組具有某一類特征的事務(wù)。類是抽象的,比如鳥類
2、實(shí)例(instance),實(shí)體是類的實(shí)體話提現(xiàn),比如一只鳥
基于原型的面向?qū)ο螅?br> 基于原型的面向?qū)ο笳Z言并不存在這種區(qū)別,基于原型的面向?qū)ο笳Z言所有的都是對(duì)象。基于原型的面向?qū)ο笳Z言有一個(gè)概念叫做原型對(duì)象,古代有一種東西叫做活字印刷術(shù),那一個(gè)個(gè)字的模版就是這里的原型對(duì)象。
Tips:React Native引入了基于類的面向?qū)ο缶幊谈拍睿@個(gè)在后面講解React基礎(chǔ)的時(shí)候來介紹
通過比較Java和JS可以了解二者的區(qū)分
五、什么是React?
A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES(一個(gè)JavaScript的用來創(chuàng)建界面的庫)
Tips:通過名字就可以看出來,ReactNative是基于React來寫的支持編寫原生App的框架
六、React的基礎(chǔ)知識(shí)
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)對(duì)象方法
render
調(diào)用React.createClass或者讓一個(gè)類繼承自class JSReactBasics extends Component都是需要提供render函數(shù)的。這個(gè)函數(shù)返回一個(gè)根的視圖,用來渲染實(shí)際的Component可視部分,例如例子中的,
render() {
return (
<TouchableHighlight
onPress={() => this.backgorundClicked()}
underlayColor = '#ddd'
style = {styles.container}
>
<Text style={styles.welcome}>{mainText}</Text>
</TouchableHighlight>
);
}
getInitialState()
在Component被加載之前調(diào)用一次,這個(gè)方法的返回值會(huì)被設(shè)置為this.state
Tips:這個(gè)方法只能在用React.createClass創(chuàng)建的時(shí)候使用,例如,在我們示例代碼中,加入一個(gè)方法
getInitialState(){
return {key:"value"}
}
會(huì)提示如下警告
getDefaultProps()
在Class 創(chuàng)建的時(shí)候,調(diào)用一次,這個(gè)方法在調(diào)用的時(shí)候,任何實(shí)例還沒有被創(chuàng)建。還有一點(diǎn)要注意,這個(gè)方法返回的任何Object 對(duì)象,在各個(gè)實(shí)例中是共享的,而不是每個(gè)實(shí)例一個(gè)copy。
statics
statics對(duì)象,用來定義Components可以調(diào)用的靜態(tài)方法,例如
var MyComponent = React.createClass({
statics: {
customMethod: function(foo) {
return foo === 'bar';
}
},
render: function() {
}
});
MyComponent.customMethod('bar'); // true
5、生命周期
componentWillMount
在最初的渲染之前調(diào)用一次,在React中,設(shè)置this.state會(huì)導(dǎo)致重新渲染,但是componentWillMount設(shè)置this.state并不會(huì)對(duì)導(dǎo)致render調(diào)用多次
componentDidMount
在渲染結(jié)束后,調(diào)用一次
componentWillReceiveProps
在component接收到新的參數(shù)前調(diào)用,在這個(gè)方法中調(diào)用this.setState不會(huì)觸發(fā)二次渲染,第一次渲染的時(shí)候不會(huì)調(diào)用這個(gè)方法
shouldComponentUpdate
boolean shouldComponentUpdate(
object nextProps, object nextState
)
在每次重新觸發(fā)渲染之前調(diào)用,其中nextProps和nextState分別對(duì)應(yīng)下一個(gè)狀態(tài)的參數(shù)和狀態(tài)對(duì)象。可以在這個(gè)方法中返回false來取消本次渲染。
例如
shouldComponentUpdate: function(nextProps, nextState) {
return nextProps.id !== this.props.id;
}
componentWillUpdate
在重新渲染之前調(diào)用
Warning:這個(gè)方法里不能調(diào)用this.setState()否則會(huì)陷入死循環(huán)
componentDidUpdate
在渲染之后調(diào)用
componentWillUnmount
在被刪除之前調(diào)用
為了更好的理解生命周期,我們來用React的風(fēng)格重寫示例代碼
重寫整個(gè)類
var JSReactBasics = React.createClass({
getInitialState(){
console.log("getInitialState");
return {key:"點(diǎn)擊屏幕任意位置"}//設(shè)置最初的值
},
componentWillMount(){
console.log("componentWillMount");
},
componentDidMount(){
console.log("componentDidMount");
},
shouldComponentUpdate(nextProps,nextState){
console.log("shouldComponentUpdate");
return true
},
componentWillUpdate(nextProps,nextState){
console.log("componentWillUpdate");
},
componentDidUpdate(prevProps,prevState){
console.log("componentDidUpdate");
},
render() {
return (
<TouchableHighlight
onPress={() => this.backgorundClicked()}
underlayColor = '#ddd'
style = {styles.container}
>
<Text style={styles.welcome}>{this.state.key}</Text>
</TouchableHighlight>
);
},
backgorundClicked(){
this.setState({
key:"設(shè)置了新的值"
});
}
});
然后,save,Command+R,會(huì)看到Log以及效果
2016-04-20 16:06:52.904 [info][tid:com.facebook.react.JavaScript] getInitialState
2016-04-20 16:06:52.904 [info][tid:com.facebook.react.JavaScript] componentWillMount
2016-04-20 16:06:52.909 [info][tid:com.facebook.react.JavaScript] componentDidMount
然后,點(diǎn)擊屏幕任何位置,會(huì)看到Log和截圖
2016-04-20 16:08:23.704 [info][tid:com.facebook.react.JavaScript] shouldComponentUpdate
2016-04-20 16:08:23.704 [info][tid:com.facebook.react.JavaScript] componentWillUpdate
2016-04-20 16:08:23.707 [info][tid:com.facebook.react.JavaScript] componentDidUpdate