此屏幕从其他屏幕导航。当此屏幕打开时,它将从Webhost数据库加载一些数据并将其填充到视图控件中。在构造函数(State)中定义的变量很少,但是当程序试图调用ShowAll()
函数(单击Show Button)以显示具有已定义变量的内容的警报消息时,程序显示此错误。
错误:undefined不是对象(评估' 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()
函数时,它变为未定义。
当代码已存在时,为什么/如何变得不确定?
答案 0 :(得分:0)
在渲染中绑定
onChange={this.handleChange.bind(this)}
如果您使用ES6类并且想要在渲染中调用函数,则React不再自动对象。解决此问题的一种方法是在render中调用bind。但这种做法实际上并不好。因为该函数在每次渲染时都会重新分配。所以,有几种方法可以做到。
在渲染中使用箭头功能
此方法类似于渲染方法中的绑定。您可以通过在render中使用箭头函数来避免更改此上下文:
onChange={e => this.handleChange(e)}
这是执行相同操作的另一种方法,但性能仍与渲染中的绑定相同。唯一不同的是你没有使用'this'。
在构造函数中绑定
避免在render中绑定的一种方法是在构造函数中绑定。
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
这是React文档中目前建议的“在您的应用程序中提高性能”的方法。您只需绑定一次,并在每次按下渲染中的按钮时使用。