+-
如何在React Native中显示加载按钮按POST请求?

我正在我的React Native项目中创建一个Register页面。在此页面中,在用户按下“注册”按钮后填写表单后,将调用一个POST请求。虽然POST请求响应需要一些时间,但我想在我的屏幕上显示加载,直到我收到服务器的任何响应。

这是我的代码 -

    import React from 'react';
    import { StyleSheet, Text, View, ScrollView,  TextInput,
  Button,
  TouchableHighlight,
  Image,
  Alert, ActivityIndicator } from 'react-native';

class WelcomeScreen extends React.Component {

  constructor() {
    super();
    this.state = {
      first_name:'',
      last_name:'',
      email   : '',
      mobile: '',
      password:'',
      confirmPassword:'',
      showLoader:false
    }
  };


  showLoader = () => { this.setState({ showLoader:true }); };
  hideLoader = () => { this.setState({ showLoader:false }); };

 doSignup(){
   this.showLoader();
 }

  updateValue(text, field) {
    if(field == 'first_name') {
      this.setState({
        first_name: text
      })
    }
    else if(field == 'last_name') {
      this.setState({
        last_name : text
      })
    }

    else if(field == 'email') {
      this.setState({
        email : text
      })
    }

    else if(field == 'mobile') {
      this.setState({
        mobile : text
      })
    }

    else if(field == 'password') {
      this.setState({
        password : text
      })
    }

    else if(field == 'confirmPassword') {
      this.setState({
        confirmPassword : text
      })
    }


  }

  onClickListener = (viewId) => {
    Alert.alert("Alert", "Button pressed "+viewId);
  }



  submit() {
    let collection = {}

    collection.first_name = this.state.first_name,
    collection.last_name = this.state.last_name,
    collection.email = this.state.email,
    collection.mobile = this.state.mobile
    collection.password = this.state.password,



    console.log('#HELLO:', collection);

    var url = 'my url';

    if(collection.first_name != '' && collection.last_name != '' &&
    collection.email != '' && collection.mobile != '' &&
    collection.password != '') {

      if(this.state.password === this.state.confirmPassword) {


        fetch(url, {
          method: 'POST',
          body: JSON.stringify(collection),
          headers: new Headers({
            'Content-Type' : 'application/json',
            'token': 'token'
          })
        }).then(res => res.json())
        .catch(error=> console.error('Error:', error))
        .then(response => console.log('Success:', response));

      } else {
        Alert.alert('Password and Confirm Password didn\'t match');
      }


    } else {
      Alert.alert('Please fill up the required field');
    }




  }



  render() {
    return (

      <ScrollView keyboardShouldPersistTaps={'handled'}>

      <View style={styles.container}>
        <View style={styles.inputContainerEmail}>
          <Image style={styles.inputIcon} source={{uri: 'https://png.icons8.com/message/ultraviolet/50/3498db'}}/>
          <TextInput style={styles.inputs}
              placeholder="Email"
              keyboardType="email-address"
              underlineColorAndroid='transparent'
              onChangeText={(text) => this.updateValue(text, 'email')}/>
        </View>

        <View style={styles.inputContainer}>
          <Image style={styles.inputIcon} source={{uri: 'https://png.icons8.com/key-2/ultraviolet/50/3498db'}}/>
          <TextInput style={styles.inputs}
              placeholder="Password"
              secureTextEntry={true}
              underlineColorAndroid='transparent'
              onChangeText={(text) => this.updateValue(text, 'password')}/>
        </View>

        <View style={styles.inputContainer}>
          <Image style={styles.inputIcon} source={{uri: 'https://png.icons8.com/key-2/ultraviolet/50/3498db'}}/>
          <TextInput style={styles.inputs}
              placeholder="Confirm Password"
              secureTextEntry={true}
              underlineColorAndroid='transparent'
              onChangeText={(text) => this.updateValue(text, 'confirmPassword')}/>
        </View>

        <View style={styles.inputContainer}>
          <Image style={styles.inputIcon} source={{uri: 'https://img.icons8.com/ultraviolet/40/000000/administrator-male.png'}}/>
          <TextInput style={styles.inputs}
              placeholder="First Name"
              secureTextEntry={true}
              underlineColorAndroid='transparent'
              onChangeText={(text) => this.updateValue(text, 'first_name')}/>
        </View>


        <View style={styles.inputContainer}>
          <Image style={styles.inputIcon} source={{uri: 'https://img.icons8.com/ultraviolet/40/000000/administrator-male.png'}}/>
          <TextInput style={styles.inputs}
              placeholder="Last Name"
              secureTextEntry={true}
              underlineColorAndroid='transparent'
              onChangeText={(text) => this.updateValue(text, 'last_name')}/>
        </View>


        <View style={styles.inputContainer}>
          <Image style={styles.inputIcon} source={{uri: 'https://img.icons8.com/ultraviolet/40/000000/phone.png'}}/>
          <TextInput style={styles.inputs}
              placeholder="Phone No."
              secureTextEntry={true}
              underlineColorAndroid='transparent'
              textContentType='telephoneNumber'
              onChangeText={(text) => this.updateValue(text, 'mobile')}/>
        </View>

        <TouchableHighlight style={[styles.buttonContainer, styles.loginButton]} onPress=
        {()=>{this.submit(); this.doSignup;}}>
          <Text style={styles.loginText}>Register</Text>
        </TouchableHighlight>

        <TouchableHighlight style={styles.buttonContainer} onPress={() => this.onClickListener('restore_password')}>
            <Text>Forgot your password?</Text>
        </TouchableHighlight>

        <TouchableHighlight style={styles.buttonContainerRegister} onPress={() => this.onClickListener('register')}>
            <Text>Sign In</Text>
        </TouchableHighlight>
      </View>


      <View style={{ position: 'absolute', top:"50%",right: 0, left: 0 }}>
      <ActivityIndicator animating={this.state.showLoader} size="large" color="red" />
    </View>

      </ScrollView>
    );
  }
}

我试过以下解决方案 -

Show loader when button is clicked in react native

但是他们都没有在我的案例中工作。我不明白为什么按下注册按钮后没有显示加载,因为响应需要一些时间。所以,如果有人帮助找到问题并给出解决方案的建议,那将是非常好的。

1
投票

您将加载视图放在ScrollView中,这可能会影响定位。最好将ScrollView包装在包含的View中,并将加载View作为ScrollView的兄弟放置,使用条件渲染显示它。

render() {
    return <View style={{flex: 1}}>
        <ScrollView style={{flex: 1}}>
            {/* contents here */}
        </ScrollView>
        {
            this.state.showLoader && <View style={{ position: 'absolute', top:"50%",right: 0, left: 0 }}>
                <ActivityIndicator size="large" color="red" />
            </View>
        }
    </View>;
}