React Native - 定义的状态无法使用

时间:2018-03-12 06:05:22

标签: javascript android react-native ecmascript-6 react-native-android

此屏幕从其他屏幕导航。当此屏幕打开时,它将从Webhost数据库加载一些数据并将其填充到视图控件中。在构造函数(State)中定义的变量很少,但是当程序试图调用ShowAll()函数(单击Show Button)以显示具有已定义变量的内容的警报消息时,程序显示此错误。

错误:undefined不是对象(评估' this.state.RecipeName')

enter image description here

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>
);
}
}

enter image description here

RecipeName变量已经在Consturctor(State)中定义,它也可以被Views使用/调用。但是当进入ShowAll()函数时,它变为未定义。

当代码已存在时,为什么/如何变得不确定?

1 个答案:

答案 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文档中目前建议的“在您的应用程序中提高性能”的方法。您只需绑定一次,并在每次按下渲染中的按钮时使用。