【发布时间】:2018-03-12 06:05:21
【问题描述】:
此屏幕是从其他屏幕导航的。当此屏幕打开时,它将从 Webhost 数据库加载一些数据并将它们填充到视图控件中。在 Constructor(State) 中定义的变量很少,但是当程序试图调用ShowAll() 函数(单击显示按钮)以显示带有状态中已定义变量内容的警报消息时,程序会显示此错误。
错误:未定义不是对象(评估“this.state.RecipeName”)
export default class SecondActivity extends Component
{
static navigationOptions = { title: 'View Details',};
constructor(props) {
super(props)
this.state={
RecipeID : '',
RecipeName : '',
RecipeType : '',
RecipeIngredient : '',
RecipeStep : ''
}
}
componentDidMount(){
fetch('https://unsurfaced-cross.000webhostapp.com/getRecipeDetailRN.php', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
// Getting the id.
RecipeID: this.props.navigation.state.params.ListViewClickItemHolder
})
}).then((response) => response.json())
.then((responseJson) => {
this.setState({
RecipeID : responseJson[0].RecipeID,
RecipeName : responseJson[0].RecipeName,
RecipeType : responseJson[0].RecipeType,
RecipeIngredient : responseJson[0].RecipeIngredient,
RecipeStep : responseJson[0].RecipeStep
})
}).catch((error) => {
console.error(error);
});
}
ShowAll(){
Alert.alert(
'Alert Title',
this.state.RecipeName, // **ERROR COME FROM THIS LINE**
[
{text: 'Ask me later', onPress: () => console.log('Ask me later pressed')},
{text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'},
{text: 'OK', onPress: () => console.log('OK Pressed')},
],
{ cancelable: false }
)
}
render()
{
return(
<View style = { styles.MainContainer }>
<View style={{flex:1, flexDirection: 'column'}} >
<Text style={styles.textViewContainer} > {'Recipe ID = ' + this.state.RecipeID} </Text>
<Text style={styles.textViewContainer} > {'Recipe Name = '} </Text>
<TextInput
style={styles.textInput}
onChangeText={(text) => this.setState({RecipeName: text})}
value={this.state.RecipeName}
/>
<Text style={styles.textViewContainer} > {'Recipe Type = '} </Text>
<Picker
style={{width: 200}}
selectedValue={this.state.RecipeType}
onValueChange={
(itemValue, itemIndex) => {
this.setState({RecipeType: itemValue, isLoading:true})
this.componentDidMount()
this.forceUpdate()
}
}>
<Picker.Item label="Vegetarian" value="Vegetarian" />
<Picker.Item label="Fast Food" value="Fast Food" />
<Picker.Item label="Healthy" value="Healthy" />
<Picker.Item label="No-Cook" value="No-Cook" />
<Picker.Item label="Make Ahead" value="Make Ahead" />
</Picker>
<Text style={styles.textViewContainer} > {'Ingredient = '} </Text>
<TextInput
style={styles.textInput}
onChangeText={(text) => this.setState({RecipeIngredient: text})}
value={this.state.RecipeIngredient}
/>
<Text style={styles.textViewContainer} > {'Step = '} </Text>
<TextInput
style={styles.textInput}
onChangeText={(text) => this.setState({RecipeStep: text})}
value={this.state.RecipeStep}
/>
<Button
title="Show"
onPress={this.ShowAll}
color="#841584"
/>
</View>
</View>
);
}
}
RecipeName 变量已经在 Consturctor(State) 中定义,它也可以被 Views 使用/调用。但是当谈到ShowAll() 函数时,它变成了未定义。
当代码已经存在时,为什么/如何变得未定义?
【问题讨论】:
-
你试过 onPress={this.ShowAll.bind(this)} 吗?
-
是的,它的工作,谢谢。
-
但是通常我像上面的代码那样调用函数并没有出现任何问题,为什么要在这种情况下添加.bind(this)?实际上有什么不同? @firats
-
如果你使用 ES6 类并且你想在渲染中调用你的函数,React 不再自动绑定。解决此问题的一种方法是在渲染中调用绑定。但这种做法其实并不好。因为函数会在每次渲染时重新分配。因此,有几种方法可以做到这一点。我会在答案中解释。
-
当然,请做。
标签: javascript android react-native ecmascript-6 react-native-android