简体   繁体   中英

How to show Loading on Button press POST request in React Native?

I am making one Register page in my React Native project. In this page, after filling the form when user presses the Register button one POST request is called. While the POST request response takes some time, I want to show Loading in my screen until I get any response from server.

Here's my code-

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

I have tried the following solution-

Show loader when button is clicked in react native

But none of them worked in my case. I am not understanding why the Loading is not showing after pressing the Register button as the response is taking some time. So, it would be very nice if someone help to find the problem and give advice to solve it.

You placed the loading view inside the ScrollView, which probably messes up the positioning. Better to wrap the ScrollView in a containing View and place the loading View as a sibling of the ScrollView, show it using conditional rendering.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM