簡介
大多數組件在創建時就可以使用各種參數來進行定製。用於定製的這些參數就稱爲props(屬性)。
我們使用兩種數據來控制一個組件:props和state。props是在父組件中指定,而且一經指定,在被指定的組件的生命週期中則不再改變。 對於需要改變的數據,我們需要使用state。
props(屬性)。
以常見的基礎組件Image
爲例,在創建一個圖片時,可以傳入一個名爲source
的屬性(prop)
來指定要顯示的圖片的地址,以及使用名爲style
的屬性(prop)
來控制其尺寸。
import React, { Component } from 'react';
import { Image } from 'react-native';
export default 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}} />
);
}
}
請注意{pic}
外圍有一層括號,我們需要用括號來把pic
這個變量嵌入到JSX語句
中。括號的意思是括號內部爲一個js變量
或表達式
,需要執行後取值。因此我們可以把任意合法的JavaScript表達式
通過括號嵌入到JSX語句
中。
當然你也可以寫成這樣
import React, { Component } from 'react';
import {
Image
} from 'react-native';
export default class Bananas extends Component {
render() {
return (
<Image source={{uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'}} style={{width: 193, height: 110}} />
);
}
}
Image組件
用於顯示圖片;source屬性
指定顯示圖片的地址,有兩種指定形式:
指定本機文件:source={require('./icon.png')}
,,相對位置尋址
注:: 如果你有my-icon.ios.png
和my-icon.android.png
,Packager
就會根據平臺而選擇不同的文件。
指定網絡圖片:source={{uri: 'http://facebook.github.io/react/img/logo_og.png'}}
注:: 一般需要手動指定圖片的尺寸 style={{widtn:193,height:110}}
下面是指定本機文件的寫法
import React, { Component } from 'react';
import{ Image, View } from 'react-native'
export default class APP extends Component {
render() {
return(
<View>
<Image source={require('./img/guide.png')} />
</View>
);
}
}
自定義的組件也可以使用props
。通過在不同的場景使用不同的屬性定製,可以儘量提高自定義組件的複用範疇。只需在render
函數中引用this.props
,然後按需處理即可。
下面的例子把Greeting組件
寫在JSX語句
中,用法和內置組件並無二致,我們在Greeting組件
中將name
作爲一個屬性來定製,這樣可以複用這一組件來製作各種不同的“問候語”。
import React, { Component } from 'react';
import { Text, View } from 'react-native';
//在組件中,獲取屬性的方法如下代碼:
class Greeting extends Component {
//每一個組件中必須有一個render方法,用於輸出組件
render() {
//使用return來返回要輸出的內容
return (
<Text>Hello {this.props.name}!</Text>
);
}
}
//定義屬性:
export default class App extends Component {
render() {
return (
<View style={{alignItems: 'center'}}>
<Greeting name='zhang' />
<Greeting name='wang' />
<Greeting name='zhao' />
</View>
);
}
}
組件的用法與原生的 HTML 標籤
完全一致,可以任意加入屬性,比如<Greeting name="wang">
,就是Greeting組件
加入一個name屬性
,值爲wang
。組件的屬性可以在組件類的this.props對象
上獲取,比如name屬性
就可以通過this.props.name
讀取。
State(狀態)
我們使用兩種數據來控制一個組件:屬性(props)
和狀態(state)
。屬性(props)
是在父組件中指定,而且一經指定,在被指定的組件的生命週期中則不再改變。 對於需要改變的數據,我們需要使用狀態(state)
。
一般來說,你需要在constructor
中初始化狀態(state(譯註:這是ES6的寫法,早期的很多ES5的例子使用的是getInitialState方法來初始化state,這一做法會逐漸被淘汰)
,然後在需要修改時調用setState
方法。
假如我們需要製作一段不停閃爍的文字。文字內容本身在組件創建時就已經指定好了,所以文字內容應該是一個屬性(prop)
。而文字的顯示或隱藏的狀態(快速的顯隱切換就產生了閃爍的效果)則是隨着時間變化的,因此這一狀態應該寫到狀態(state)
中。
import React, { Component } from 'react';
import { Text, View } from 'react-native';
class Blink extends Component {
//constructor 構造函數
constructor(props) {
super(props); //執行父類的方法
this.state = { showText: true };
// 每1000毫秒對showText狀態做一次取反操作
setInterval(() => {
this.setState(previousState => {
return { showText: !previousState.showText };
});
}, 1000);
}
render() {
// 根據當前showText的值決定是否顯示text內容
let display = this.state.showText ? this.props.text : ' ';
return (
<Text>{display}</Text>
);
}
}
export default class BlinkApp extends Component {
render() {
return (
<View>
<Blink text='I love to blink' />
<Blink text='Yes blinking is so great' />
<Blink text='Why did they ever take this out of HTML' />
<Blink text='Look at me look at me look at me' />
</View>
);
}
}
constructor
我覺得在這裏有必要介紹一下constructor
屬性,當你在React class
中需要設置state
的初始值或者綁定事件時,需要加上constructor(){}
我們知道,在JavaScript
中,constructor
返回對創建此對象的數組函數的引用。
例程如下,前者輸出內容,後着輸出整個 constructor
構造函數
<script type="text/javascript">
var test=new Array();
if (test.constructor==Array)
{
document.write("This is an Array");
}
if (test.constructor==Date)
{
document.write("This is a Date");
}
</script>
輸出結果:This is an Array
<script type="text/javascript">
function employee(name,job,born)
{
this.name=name;
this.job=job;
this.born=born;
}
var bill=new employee("Bill Gates","Engineer",1985);
document.write(bill.constructor);
</script>
輸出結果:function employee(name,job,born) { this.name=name; this.job=job; this.born=born; }
而在react-native中,用法是稍微有些區別的onstructor方法
中出現了super
關鍵字,它在這裏表示父類的構造函數,用來新建父類的this對象
,子類必須在constructor方法
中調用super方法
,否則新建實例時會報錯,因爲子類沒有自己的this對象
,而是繼承父類的this對象
,然後對其進行加工。如果不調用super方法
,子類就得不到this對象
。
取反操作
// 每1000毫秒對showText狀態做一次取反操作
setInterval(() => {
this.setState(previousState => {
return { showText: !previousState.showText };
});
}, 1000);
這裏其實就是將this.state
的值作爲一個參數previousState
傳了進去,previousState.showText
跟this.state.showText
是等價的;然後要通過return
方法把值返回給state
,不然這個showText
只是作爲形參,不對外面的state
產生影響。在這裏previousState
只起到中轉作用,你可以把它改爲任意值,不影響效果,就像下面這樣
this.setState(aa => {
return { showText: !aa.showText };
});
當然如果覺得不好理解的話,也可以直接用下面這種寫法this.setState({showText: !this.state.showText});
State的工作原理和React.js完全一致,所以對於處理state的一些更深入的細節,你可以參閱React.Component API。不過上面那個英文版的看着不方便,如果想學習更多關於react的知識的話,所以強烈推薦極客學院的中文版本