組件回調函數的綁定:
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函數中,可以使用這種方式。