How to prevent multiple clicks on a button in react native?

2.9k views Asked by At

I'm working on a project that involves signing in users and it it is working fine (I'm using firebase for authentication). However for signing in to occur, it needs some time depending also on the internet connection so I need to disable the button once it is clicked and re-enable it again. Here is my code:

class Login extends Component {

    handlelogin = () => {
    this.setState.errorMessage = '';
    const {email, password} = this.state;
    auth
      .signInWithEmailAndPassword(email, password)
      .then(() => this.props.navigation.navigate('Home'))
      .catch((error) => this.setState({errorMessage: error.message}));
  };

render() {
return (

     // Some code to handle input

      <TouchableOpacity
      style={
        !this.state.email || !this.state.password
          ? styles.disabled
          : styles.button
      }
      disabled={!this.state.password || !this.state.email}
      onPress={this.handlelogin}>
      <Text style={{color: '#fff', fontWeight: '500'}}>Sign in</Text>
    </TouchableOpacity>
)}

I have tried this answer for my code to go like this but this didn't seem to work:

class Login extends Component {

    loginProcess = false;

    handlelogin = () => {
    this.setState.errorMessage = '';
    const {email, password} = this.state;
    auth
      .signInWithEmailAndPassword(email, password)
      .then(() => this.props.navigation.navigate('Home'))
      .catch((error) => {
        this.setState({errorMessage: error.message})
        this.loginProcess = false;
   });

  };

render() {
return (

     // Some code to handle input

      <TouchableOpacity
      style={
        !this.state.email || !this.state.password
          ? styles.disabled
          : styles.button
      }
      disabled={!this.state.password || !this.state.email}
      onPress={()=> {
          if (!loginProcess) {
              this.handleLogin;
              this.loginProcess = true;
          }
      }>
      <Text style={{color: '#fff', fontWeight: '500'}}>Sign in</Text>
    </TouchableOpacity>
)}

P.S This is my first question on stackoverflow, any hint for writing better questions is appreciated

1

There are 1 answers

1
yesIamFaded On BEST ANSWER

You could implement a Spinner that shows instead of the button when it is first clicked and shows the button after the call finishes.

I had the same problem not long ago - here a small example:

const MyComponent = ({makePutCall}) => {
   const [showSpinner,setShowSpinner] = useState(false);

   const handlePress = async () => {
      setShowSpinner(true);
      await makePutCall();
      setShowSpinner(false);
   }

   return showSpinner ? <Spinner/> : <Button onPress={handlePress}/>
}

as a "Spinner" just use ActivityIndicator from react-native.