react native key,ref,bind的作用和使用
阿新 • • 發佈:2019-01-05
我們在專案裡面,經常會用的批次渲染,比如一個列表渲染很多個item,或者一個橫排或者豎排同時渲染多個數據。
例如:
- render1(){
- var arr = [];
- for(var i=0;i<5;i++){
- arr.push(
- <Textstyle={{fontSize:20, color: 'red'}}>
- 這是{i}
- </Text>
- );
- }
- return (
-
<Viewstyle={[styles.container, styles.center]}
- {<spanstyle="font-family: Arial, Helvetica, sans-serif;">arr</span>}
- </View>
- );
- }
這樣寫,RN都會報一個警告,需要你對每個item新增一個key,在Text裡新增一個屬性key:
- <Textkey={i} style={{fontSize:20, color: 'red'}}>
但是這個key有什麼作用呢?我們在程式碼後面加一個console.log輸出一下看看結果:
-
for(var i=0;i<5;i++){
- ...
- }
- console.log(arr);
看到key和那個props了嗎,我們可在未渲染之前,根據要求再次更改array裡面<Text>的屬性。我們現在來改一改試試看!
先看看上面程式碼執行的效果:
然後我們在for之後這麼改看看結果如何:
- for(var i=0;i<arr.length;i++){
- if (arr[i].key == 2){
- arr[i].props.style.fontSize = 40;
-
arr[i].props.style.color
- arr[i].props.children[0] = '改變了哦';
- }
- }
結果我們可以看到,中間那個key等於2的已經改變了哦。
既然這樣,那我們繼續改一下,把這個arr改為這個元件的一個屬性:
- constructor(props){
- super(props);
- this.state = {
- blnUpdate: false,
- };
- this.testArr = [];
- for(var i=0;i<5;i++){
- this.testArr.push(
- <Textkey={i} style={{fontSize:20, color: 'red'}} onPress={this.changeChild.bind(this, i)}>
- 這是{i}
- </Text>
- );
- }
- console.log(this.testArr);
- }
另外加一個state變數,用於重新整理render(為什麼這麼做,是RN的重新整理機制,需要呼叫this.setState才會呼叫,所以弄了一個bln值,而不是把arr放在state裡面
然後在繫結還按鈕回撥中這樣做:
- changeChild(key){
- console.log(key);
- if (this.testArr[key].props.children[0] == '我變了'){
- this.testArr[key].props.style = {fontSize : 20, color : 'red'};
- this.testArr[key].props.children[0] = '這是';
- }else{
- this.testArr[key].props.style = {fontSize : 30, color : 'green'};
- this.testArr[key].props.children[0] = '我變了';
- //這裡要說說text的結構,如果text是純文字,children就只有一個,如果中間夾雜著其他變數,react是將text分段儲存的。
- }
- this.setUpdate();
- }
- setUpdate(){
- this.setState({
- blnUpdate: !this.state.blnUpdate
- });
- }
點選之前:
點選之後:
哈哈,都變了哦!!不過這樣做有點延時。其實改變渲染之後的東西,在學習RN之後會有一個專門的引數可供使用,就是每個元件的自帶屬性ref,在上面的截圖我們也看到了,現在ref是null,因為沒有設定,如果要使用需要這樣做:
- <Textkey={i} ref={'text'+i} style={{fontSize:20, color: 'red'}} onPress={this.changeChild.bind(this, i)}>
不過這個ref有個缺點,它必須要在render之後才會產生,也就是一開始初始化後,使用this.refs.text0 會報錯,這點一定要弄清楚哦!
bind
renderAllButtons(){
var allBtns = [];
titles=['拍照','視訊','開機','照明']
for(var i=0 ;i<4;i++){
let title = titles[i];
allBtns.push(
<View key={i} style={styles.autoViewStyle}>
<TouchableOpacity style={styles.buttonStyle} onPress={this._pressBtn.bind(this,i)}>
<Text style={styles.textsStyle}>{title}</Text>
</TouchableOpacity>
</View>
);
}
_pressBtn(i){
console.log(i)
}