在从本机获取API中的数据时遇到问题

时间:2018-10-16 08:39:28

标签: react-native

我正在尝试从api(type:GET)呈现数据,但是当我尝试设置它的状态时无法设置我的状态...这是我的状态和api调用的代码

constructor(props) {


super()
 constructor(props) {
        super(){this.state={gender:{}}

现在这是我的api调用

componentDidMount()
    {
axios.get("http://172.104.217.178/blaze10/public/api/genders")
.then((response) => {
    alert(JSON.stringify(response));
    this.setState({
        gender:response.data


    });
    alert(this.state.gender)

})
.catch(error => alert(JSON.stringify(error.response.data)));
     }

这是我在渲染函数中编写的代码

let gender = [];
  let stateGender = this.state.gender;
  alert(JSON.stringify(this.state.gender));
    stateGender.forEach((value, key) => {
        gender.push(<Picker.Item label={key} value={value} />);
    });

and this is my picker components code where i want to show my api data ..
<Item picker >
        <Left>
       <Text style={{paddingLeft:10,fontSize:15,fontWeight:'bold',color:this.state.backgroundColor2}}> Gender</Text>
       </Left>
       <Body>
          <Picker 
            mode="dropdown"
            iosIcon={<Icon name="ios-arrow-down-outline" />}
            style={{ width: '100%' }}

            placeholder="Select Gender"

            placeholderStyle={{ color: "#bfc6ea" }}
            placeholderIconColor="#007aff"
            selectedValue={this.state.gender1}
            onValueChange={(value)=>this.onValueChange(value,'gender')}


          >
            {/* {gender} */}
          </Picker>
          </Body>
        </Item>

面对问题

  1. 我的状态不能更新
  2. 并且当我尝试运行我的应用程序时,它给出了这样的错误,例如TypeError:stateGender不是函数

1 个答案:

答案 0 :(得分:0)

代码中发生了几件事。

首先,在使用Component的构造函数时,将道具传递给super:

official docs

  

React组件的构造函数在挂载之前被调用。   在实现React.Component子类的构造函数时,您可以   应该在其他任何语句之前调用super(props)。除此以外,   this.props将在构造函数中未定义,这可能导致   错误。

替换:

constructor(props) {
    super(){this.state={gender:{}}

具有:

constructor(props) {
    super(props);
    {this.state={gender:{}}
}

第二,成功调用api后,您可以使用setState正确设置状态,但是会弹出带有state值的警报,并且不能保证已设置状态。

这发生在这里:

this.setState({
    gender:response.data
});
alert(this.state.gender)

由于以下原因,这也许行不通:

来自official docs

  

setState()并不总是立即更新组件。它可能   批处理或将更新推迟到以后。这使得阅读this.state   在调用setState()之后立即发生潜在的陷阱。相反,使用   componentDidUpdate或setState回调(setState(updater,   回调)),保证在更新后都会触发   已应用。

现在,在渲染组件时,您正在执行以下操作:

let gender = [];
let stateGender = this.state.gender;
stateGender.forEach((value, key) => {
    gender.push(<Picker.Item label={key} value={value} />);
});

由于stateGender是对象(您将其初始化为this.state={gender:{}}),因此无法直接使用forEach对其进行迭代,而只能使用Object.keys来获取对象的键,然后遍历物体。另外,请确保stateGender已初始化:

if(stateGender){
    Object.keys(stateGender).forEach((key) => {
        if(stateGender.hasOwnProperty(key)){
            gender.push(<Picker.Item label={key} value={stateGender[key]} />);
        }
    });
}

建议

我强烈建议您在渲染器中替换此行:

{/* {gender} */}

与此:

{
Object.keys(stateGender).forEach((key) => {
    if(stateGender.hasOwnProperty(key)){
        return (<Picker.Item label={key} value={stateGender[key]} />);
    }
});
}

因此,您不需要gender变量。 不要忘记验证stateGender是否未定义,它是一个对象还是具有键。

您的组件应如下所示:

 constructor(props){
    super(props);
    this.state = { gender:{} }
  }
  componentDidMount() {
    axios.get("http://172.104.217.178/blaze10/public/api/genders")
      .then((response) => {
        this.setState({
          gender: response.data
        });
      })
      .catch(error => alert(error.message));
  }

  render(){
    let stateGender = this.state.gender;
    // To test if stateGender has keys. If the following alert doesn't return anything, then it will never render the items.
    alert('keys: ' + JSON.stringify(Object.keys(stateGender))); 

    return(
    <View>
      <Left>
        <Text style={{ paddingLeft: 10, fontSize: 15, fontWeight: 'bold', color: this.state.backgroundColor2 }}> Gender</Text>
      </Left>
      <Body>
        <Picker
          mode="dropdown"
          iosIcon={<Icon name="ios-arrow-down-outline" />}
          style={{ width: '100%' }}
          placeholder="Select Gender"
          placeholderStyle={{ color: "#bfc6ea" }}
          placeholderIconColor="#007aff"
          selectedValue={this.state.gender1}
          onValueChange={(value) => this.onValueChange(value, 'gender')}>
          {
            Object.keys(stateGender).forEach((key) => {
              if (stateGender.hasOwnProperty(key)) {
                return (<Picker.Item label={key} value={stateGender[key]} />);
              }
            })
          }
        </Picker>
      </Body>
      </View>
    );
  }