函數可以稱得上是編程語言的靈魂所在之處,它就像是一個個工廠,總能創造出開發者需要的效果。本文就將介紹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應用在渲染界面時的性能。