1. 程式人生 > >react native key,ref,bind的作用和使用

react native key,ref,bind的作用和使用

我們在專案裡面,經常會用的批次渲染,比如一個列表渲染很多個item,或者一個橫排或者豎排同時渲染多個數據。

例如:

  1. render1(){  
  2.   var arr = [];  
  3.   for(var i=0;i<5;i++){  
  4.     arr.push(  
  5.       <Textstyle={{fontSize:20, color: 'red'}}>
  6.         這是{i}  
  7.       </Text>
  8.     );  
  9.   }  
  10.   return (  
  11.     <Viewstyle={[styles.container, styles.center]}
    >
  12.       {<spanstyle="font-family: Arial, Helvetica, sans-serif;">arr</span>}  
  13.     </View>
  14.   );  
  15. }  

這樣寫,RN都會報一個警告,需要你對每個item新增一個key,在Text裡新增一個屬性key:
  1. <Textkey={i} style={{fontSize:20, color: 'red'}}>

但是這個key有什麼作用呢?我們在程式碼後面加一個console.log輸出一下看看結果:

  1. for(var i=0;i<5;i++){  
  2.   ...  
  3. }  
  1. console.log(arr);  
輸出結果顯示,arr所有的內容,包括那個key:


看到key和那個props了嗎,我們可在未渲染之前,根據要求再次更改array裡面<Text>的屬性。我們現在來改一改試試看!

先看看上面程式碼執行的效果:


然後我們在for之後這麼改看看結果如何:

  1. for(var i=0;i<arr.length;i++){  
  2.   if (arr[i].key == 2){  
  3.     arr[i].props.style.fontSize = 40;  
  4.     arr[i].props.style.color
     = 'green';  
  5.     arr[i].props.children[0] = '改變了哦';  
  6.   }  
  7. }  


結果我們可以看到,中間那個key等於2的已經改變了哦。

既然這樣,那我們繼續改一下,把這個arr改為這個元件的一個屬性:

  1. constructor(props){  
  2.   super(props);  
  3.   this.state = {  
  4.     blnUpdate: false,  
  5.   };  
  6.   this.testArr = [];  
  7.   for(var i=0;i<5;i++){  
  8.     this.testArr.push(  
  9.       <Textkey={i} style={{fontSize:20, color: 'red'}} onPress={this.changeChild.bind(this, i)}>
  10.         這是{i}  
  11.       </Text>
  12.     );  
  13.   }  
  14.   console.log(this.testArr);  
  15. }  
定義在constructor裡面,並且附初始值,我們還綁定了一個按鍵響應, 可以看到臨時變化。

另外加一個state變數,用於重新整理render(為什麼這麼做,是RN的重新整理機制,需要呼叫this.setState才會呼叫,所以弄了一個bln值,而不是把arr放在state裡面

然後在繫結還按鈕回撥中這樣做:

  1. changeChild(key){  
  2.   console.log(key);  
  3.   if (this.testArr[key].props.children[0] == '我變了'){  
  4.     this.testArr[key].props.style = {fontSize : 20, color : 'red'};  
  5.     this.testArr[key].props.children[0] = '這是';  
  6.   }else{  
  7.     this.testArr[key].props.style = {fontSize : 30, color : 'green'};  
  8.     this.testArr[key].props.children[0] = '我變了';  
  9.     //這裡要說說text的結構,如果text是純文字,children就只有一個,如果中間夾雜著其他變數,react是將text分段儲存的。  
  10.   }  
  11.   this.setUpdate();  
  12. }  
  1. setUpdate(){  
  2.   this.setState({  
  3.     blnUpdate: !this.state.blnUpdate  
  4.   });  
  5. }  
這樣我們來看效果:

點選之前:

點選之後:

哈哈,都變了哦!!不過這樣做有點延時。其實改變渲染之後的東西,在學習RN之後會有一個專門的引數可供使用,就是每個元件的自帶屬性ref,在上面的截圖我們也看到了,現在ref是null,因為沒有設定,如果要使用需要這樣做:

  1. <Textkey={i} ref={'text'+i} style={{fontSize:20, color: 'red'}} onPress={this.changeChild.bind(this, i)}>
然後使用的時候就是this.refs.text0.xxx,這個RN給我們提供一個很有用的函式,this.refs.text0.setNativeProps({style:{xxx},xxx:xxx}),這個是直接改變原生元件的屬性,是不會經過render的,有時候可以提高效能。

不過這個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)
  }