ReactNative之組件回調函數的綁定

組件回調函數的綁定:

import React from 'react';
import {
  StyleSheet,
  Text,
  View,
  Dimensions,
  TextInput,
} from 'react-native';
export interface IProps {

}
export interface IState {
  inputedNum: string,
  inputedPW: string
}
export default class Test extends React.Component<IProps ,IState>{
  constructor(props){
    super(props);
    this.state = {
      inputedNum: '',
      inputedPW: ''
    };
    // this.updatePW = this.updatePW.bind(this);
  }
  updateNum(newText) {
    console.log('this in update num');
    console.log(this);
    this.setState((state)=>{
      return {
        inputedNum: newText,
      };
    });
  }
  updatePW(newText) {
    this.setState((state)=>{
      return {
        inputedPW: newText,
      };
    });
  }
  render(){
    console.log('this in render');
    console.log(this);
    return (
      <View style={styles.container}>
        <TextInput 
        style={styles.textInputStyle}
        placeholder={'請輸入手機號'}
        onChangeText={(newText)=>this.updateNum(newText)}
        />
        <Text style={styles.textPromptStyle}>
          你輸入的手機號:{this.state.inputedNum}
        </Text>
        <TextInput
        style={styles.textInputStyle}
        placeholder={'請輸入密碼'}
        password={true}
        onChangeText={(newText)=>this.updatePW}
        />
        <Text style={styles.bigTextPrompt}>
          確定
        </Text>
      </View>
    );
  }
} 
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white',
  },
  textInputStyle: {
    margin:50,
    height:40,
    backgroundColor: 'gray',
    fontSize: 20,
  },
  textPromptStyle: {
    margin: 30,
    fontSize: 20,
  },
  bigTextPrompt: {
    margin: 30,
    backgroundColor: 'gray',
    textAlign: 'center',
    color: 'white',
    fontSize: 30,
  }
});

運行的界面:

我們看到了兩種不同的綁定方法,爲什麼要綁定以及不同的綁定實現方式?

在代碼中我們在render函數retrun語句前的語句:

console.log('this in render.');

console.log(this);

在updateNum函數的最開始處也加兩個語句:

console.log('this in update num');
console.log(this);

從代碼中我們可以看的:

// this.updatePW = this.updatePW.bind(this);

這行代碼是註釋掉的。

現在讓我們執行代碼,在手機號輸入框中隨意輸入一個字符,手機會出現大紅屏顯示,

日誌輸出:

從日誌中,我們可以看到,當render函數被執行時,this指向Test類的一個實例。而在constructor函數中加入語句this.updateNum=this.updateNum.bind(this);當updateNum函數被執行時,this指針

指向了Test類的實例。

通過上面的實驗可得知:綁定操作是爲了讓回調函數能正確的解析出this。如果回調函數使用

剪頭函數方式來回調,則不需要綁定。如果開發者在調用回調函數時使用了簡寫方式,就需要綁定。

最後總結一下回調函數的四種寫法。

(1)使用箭頭函數指向回調。

onChangeText={(newText)=>this.updateNum(newText)}

這種寫法,不需要使用bind函數來綁定。

(2)回調函數使用箭頭函數來定義。在代碼2-5-1中,將updateNum函數的定義改爲:

updateNum(newText) {
    this.setState((state)=>{
      return {
        inputedNum: newText,
      };
    });
  }

然後在JSX代碼中就可以寫

onChangeText=(this.updateNum)

這種寫法,也不需要使用bind函數來綁定,這種方法方便快捷,但它的寫法與正規的類成員定義相左,有些開發者不喜歡。

(3)在構造函數中進行綁定。如代碼中我們在構造函數中綁定了updatePW函數,然

後在下面直接使用

onChangeText=(this.updatePW)

(4)第四種寫法算是第三種寫法的簡化寫法。在構造函數中不綁定updatePW函數(將相

應語句去掉),然後在下面使用

onChangeText=(this.updatePW.bind(this)}

這種寫法簡單,但它的缺點是每次render時,都會執行一次bind函數(第三種寫法只會在對象初始化時執行一次)。強烈建議開發者在RN組件的render函數中不要使用這種綁定方式,它確實降低了RN應用在渲染界面時的性能表現。但在非render函數中,可以使用這種方式。

發佈了147 篇原創文章 · 獲贊 21 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章