RN之回調函數-百步九折縈巖巒

2018-05-02 10:36:03 浏览数 (1)

函數可以稱得上是編程語言的靈魂所在之處,它就像是一個個工廠,總能創造出開發者需要的效果。本文就將介紹RN中回調函數的四種寫法。

方法一:使用箭頭函數指向回調。這種寫法就不需要bind函數來綁定。{(newText)this.updateNum=>this.updateNum(newText)}這句代碼的意思是在花括號中有一個箭頭符號定義的函數,它將收到的字符串為參數調用本類組件的updateNum函數,并將該函數的返回值返回。

代码语言:javascript复制
//構造函數
constructor(props) {
     super(props);
       //狀態機
     this.state = {
         inputedNum: '',
         inputedPW:''
     };
}
//定義一個函數
updateNum(newText) {
   this.setState(state) => {
         return {
               intputedNum:newText,  
         }
   }  
}
//調用  
render() {
   return (
       <TextInput
             onChangeText = {(newText)this.updateNum=>this.updateNum(newText)}/>
 );
}

這裡需要解釋一下綁定。在RN中,綁定操作就是為了讓回調函數能夠正確的解析出this。比如說下面的這段代碼。將updateNum寫成簡寫形式,在return前面加上一條語句console.log(this)。

代码语言:javascript复制
//構造函數
constructor(props) {
      super(props);
        //狀態機
      this.state = {
          inputedNum: '',
          inputedPW:''
      };
 }
//定義一個函數
updateNum(newText) {
    this.setState(state) => {
      //加上這句會報錯
        console.log(this);
          return {
                intputedNum:newText,  
          }
    }  
}
//調用  用簡寫的方式調用updateNum函數
render() {
     console.log(this);
    return (
        <TextInput
              onChangeText = {this.updateNum}/>
  );
}

如果按照上述方式這樣寫就會報錯,因為當render函數被執行時,this指向本類的一個實例,而當updateNum函數被執行時,this指向了一個對象,它不是該類的實例,因此沒有setState方法,從而產生異常。

方法二:回調函數使用箭頭來定義。這種寫法也不需要bind函數進行綁定。

代码语言:javascript复制
//可以將函數定義成這樣
updateNum = (newText){
      this.setState((state) => {
         return {
            inputedNum: newText,
    }
});
}
//JSX代碼中就可以寫成如下形式
onChangeText = {this.updateNum}

方法三:在構造函數中進行綁定,後面就可以直接用簡寫的方式調用。

代码语言:javascript复制
  //構造函數
constructor(props) {
      super(props);
        //狀態機
      this.state = {
          inputedNum: '',
          inputedPW:''
      };
    //注意!!!這裡進行綁定
    this.updateNum = this.updateNum.bind(this);
 }
//定義一個函數
updateNum(newText) {
    this.setState(state) => {
          return {
                intputedNum:newText,  
          }
    }  
}
//調用  用簡寫的方式調用updateNum函數
render() {
    return (
        <TextInput
              onChangeText = {this.updateNum}/>
  );
}

這種方式是簡化了操作,但是千萬要注意,不能寫成下面這個樣子

代码语言:javascript复制
  //錯誤示範
    onChangeText = {this.updateNum(newText)}

在ES6語法中,this.updateNum是一個使用function關鍵字定義的變量,在這裡function關鍵字被省略了而已。它指向的是我們已經定義好的函數,所以 onChangeText = {this.updateNum}能正確對應寫好的處理函數。而上面這種錯誤示範,在運行的時候會導致結果未知的情況出現。因為newText沒有定義。有函數箭頭時,newText是代表形參,但是上面這張沒有箭頭函數時,newText已經沒有定義了。並且,這條語句代表的是這條語句的一個返回值,而在本例中updateNum函數沒有返回值,那麼它的值就是undefined,將接口與undefined相接明顯是不合適的。在某些程序出現編譯通過但是手機白屏的情況,就可能是因為這種寫法引起的。

方法四:與方法三類似,但是它不用去構造函數中綁定updateNum函數,只要按照下面這種寫法就可以了。

代码语言:javascript复制
//調用  用簡寫的方式調用updateNum函數
render() {
    return (
        <TextInput
              onChangeText = {this.updateNum.bind(this)}/>
  );
}

這種寫法更為簡單,但是它的缺點是在每次render時,都執行一次bind函數。這有可能降低了RN應用在渲染界面時的性能。

0 人点赞