![](/img/trans.png)
[英]A question on variable handling in asynchronous functions. Will this code cause inconsistency?
[英]ReactNative nested render functions. Question regarding `this` between objects and functions
這是我的困惑:
constructor(props) {
super(props);
}
hookNav(){
console.log("work");
}
renderItem({ item, index }) {
return (
<TouchableOpacity style={{ margin: 9 }} onPress={this.hookNav}>
<View
style={{
flex: 1,
minWidth: 170,
maxWidth: 223,
height: 280,
maxHeight: 280,
borderRadius: 10,
}}
>
<ImageBackground
source={{
uri: "https://picsum.photos/170/223",
}}
style={{ flex: 1 }}
imageStyle={{ borderRadius: 10 }}
>
<Text
style={{
color: "white",
position: "absolute",
bottom: 20,
right: 10,
fontWeight: "bold",
textShadowColor: "black",
textShadowOffset: { width: -1, height: 1 },
textShadowRadius: 10,
}}
>
Topic
</Text>
</ImageBackground>
</View>
</TouchableOpacity>
);
}
render(){
return (
<View style={{ marginBottom: 80, backgroundColor: "white" }}>
<Header
centerComponent={{ text: "test", style: { color: "orange" } }}
rightComponent={{ icon: "add", color: "orange" }}
/>
<FlatList
numColumns={2}
onEndReachedThreshold={0}
onEndReached={({ distanceFromEnd }) => {
console.debug("on end reached ", distanceFromEnd);
}}
contentContainerStyle={styles.list}
data={[
{ key: "a" },
{ key: "b" },
{ key: "c" },
{ key: "d" },
{ key: "e" },
{ key: "f" },
]}
renderItem={this.renderItem}
ListHeaderComponent={
<Text
style={{ padding: 10, fontWeight: "bold" }}
>
Your Topics
</Text>
}
/>
</View>
);
}
}
在上面的這段代碼中,當導航到這個頁面時,會立即拋出this.hookNav
未定義的錯誤。
但是,當我將hookNav
function 放在 state object 內部時,就像這樣
constructor(props) {
super(props);
state = {
hookNav : function() {
console.log("work please");
}
}
}
並且在onPress
里面的renderItem
const { hookNav} = this.state;
return (
<TouchableOpacity style={{ margin: 9 }} onPress={hookNav}>
這按預期工作。
據我了解, render
已經可以通過this
訪問組件的state
。 如果renderItem
可以通過this
訪問state
object,為什么不能直接訪問this.hookNav()
呢? 為什么 function 需要封裝在 object 中才能正常工作?
謝謝。
這是因為this
在任何 Javascript function 中的值取決於 function 的調用方式。
在您的非工作示例中, this.hookNav
位於renderItem
方法內。 因此它將采用該方法的this
——正如我剛才所說,這取決於它的調用方式。 進一步檢查您的代碼表明renderItem
方法不是由您的組件直接調用,而是作為FlatList
組件的 prop(稱為renderItem
)傳遞。 現在我不知道該組件是如何實現的(我從未使用過 React Native),但幾乎可以肯定它有時會調用 function - 當它調用時,它不能在你的組件的上下文中。 這是因為FlatList
不可能知道 function prop 來自哪里,並且當它調用它時,它將被視為“普通” function,而不是在任何特定 ZA8CFDE63131BD59EB2AC9C68F 的上下文中。 所以它的this
上下文不會像預期的那樣是你的組件實例,而只是全局 object - 它沒有任何hookNav
方法。
在第二個示例中不會出現此問題,因為您只需訪問 function 作為this.state
的一部分 - 沒有傳遞方法,如前一個示例中的renderItem
,這取決於內部this
引用。 請注意,如果您的hookNav
在其中引用this
,則情況並非如此。
this
上下文的問題在 React 中很常見,但幸運的是有兩個通用的解決方案可以解決這個問題:
在組件的構造函數中綁定方法。 如果構造函數在第一個示例中包含語句this.renderItem = this.renderItem.bind(this);
,那么它會正常工作。 (請注意,在官方 React文檔中建議這樣做。)從技術上講,它是“最佳”解決方案(性能略好於其他選項)-但如果您有很多需要此類綁定的方法,則確實涉及相當多的樣板文件.
使用箭頭函數來定義方法。 而不是renderItem({ item, index }) {...}
,將其寫為renderItem = ({ item, index }) => {...}
。 這是有效的,因為箭頭函數采用了其詞匯 scope 的this
,這將是 class 本身 - 所以換句話說, this
將始終引用組件實例,正如您幾乎總是想要的那樣。
如果這令人困惑,請不要擔心 - JS 中this
關鍵字的行為對於 JS 初學者來說是一個常見的絆腳石,對於那些更有經驗的人來說通常也足夠了。 網上有很多很好的解釋可以揭開它的神秘面紗,其中我特別推薦這個。
您必須將方法綁定this
您的 class 中。 一種方法如下所示。
constructor(props){
super(props);
this.renderItem = this.renderItem.bind(this);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.