Search code examples
reactjsreact-nativereduxsetstate

ReactNative State doesn't change immediately so how can I do to fix my problem?


I have a problem to deal with setState() in reactNative.

In the "login" module, I need to check in Firebase if a "username" is associated to an email address. If it is the case, User is authentified. If not, I make an alert saying "username don't match with an email.

So, what's my problem? When a username is not relied to an email, it works and it displays an alert dialog. When a username matches with an email, it works but it still displays an alert when I click on the button "Connecter".

Form Final result : you can see it works but an alert is displayed too

How can I do to fix this in my code ?

class ModalLogin extends React.Component {
state = {
email: '',
password: '',
pseudo: '',
items: [],
find: '',
iconEmail: require('../Images/icon-email.png'),
iconPassword: require('../Images/icon-password.png'),
iconName: require('../Images/name.png'),
isSuccessful: false,
isLoading: false,
scale: new Animated.Value(1),
translateY: new Animated.Value(0),
top: new Animated.Value(screenHeight),
};

handleLogin = () => {
const email = this.state.email;
const password = this.state.password;
const pseudo = this.state.pseudo;

if ((pseudo != '') & (email != '') & (password != '')) {
  let user_pseudo = firebase.database().ref('/users');

  user_pseudo.once('value').then(snapshot => {
    snapshot.forEach(el => {
      if (
        pseudo === el.val().username &&
        email.toLowerCase() === el.val().email
      ) {
        this.state.find = true;
        this.setState({find: true}, () => {
          this.setState({isLoading: true});
          firebase
            .auth()
            .signInWithEmailAndPassword(email, password)
            .catch(error => {
              if (error.code === 'auth/user-not-found') {
                this.handleSingin().bind(this);
              } else Alert.alert('Error', error.message);
            })
            .then(response => {
              this.setState({isLoading: false});

              if (response) {
                // Successful
                this.setState({
                  isSuccessful: true,
                });
                //storage

                this.storeName(this.state.user);
                //this.fetchUser();
                this.props.updateName(this.state.user);

                setTimeout(() => {
                  Keyboard.dismiss();
                  this.props.closeLogin();
                  this.setState({
                    isSuccessful: false,
                  });
                }, 1000);
              }
            });
          this.setState({isLoading: false});
        });
      }
    });
  });



if (this.state.find == false) {
        Alert.alert('Le pseudo ne correspond pas à son adresse email !');
        // it means no username corresponds to this email address
      }
} else {
  console.log('erreur null');
  Alert.alert(
    'Error',
    "login/password don't match!",
  );
 }
};

Thank you in advance !!


Solution

  • ok its not a react problem its just javascript as this

    if (this.state.find == false) {
              Alert.alert('Le pseudo ne correspond pas à son adresse email !');
              // it means no username corresponds to this email address
            }
    

    will be called before snapshot.forEach() the whole code in .then() function will be executed after the promise finishes so this part here

    if (this.state.find == false) {
                  Alert.alert('Le pseudo ne correspond pas à son adresse email !');
                  // it means no username corresponds to this email address
                }
    

    will always be called u should add it inside instead like that

    class ModalLogin extends React.Component {
      state = {
      email: '',
      password: '',
      pseudo: '',
      items: [],
      find: '',
      iconEmail: require('../Images/icon-email.png'),
      iconPassword: require('../Images/icon-password.png'),
      iconName: require('../Images/name.png'),
      isSuccessful: false,
      isLoading: false,
      scale: new Animated.Value(1),
      translateY: new Animated.Value(0),
      top: new Animated.Value(screenHeight),
      };
    
      handleLogin = () => {
      const email = this.state.email;
      const password = this.state.password;
      const pseudo = this.state.pseudo;
    
      if ((pseudo != '') & (email != '') & (password != '')) {
        let user_pseudo = firebase.database().ref('/users');
    
        user_pseudo.once('value').then(snapshot => {
          let find = false;
          snapshot.forEach(el => {
            if (
              pseudo === el.val().username &&
              email.toLowerCase() === el.val().email
            ) {
              find = true;
              this.setState({find: true}, () => {
                this.setState({isLoading: true});
                firebase
                  .auth()
                  .signInWithEmailAndPassword(email, password)
                  .catch(error => {
                    if (error.code === 'auth/user-not-found') {
                      this.handleSingin().bind(this);
                    } else Alert.alert('Error', error.message);
                  })
                  .then(response => {
                    this.setState({isLoading: false});
    
                    if (response) {
                      // Successful
                      this.setState({
                        isSuccessful: true,
                      });
                      //storage
    
                      this.storeName(this.state.user);
                      //this.fetchUser();
                      this.props.updateName(this.state.user);
    
                      setTimeout(() => {
                        Keyboard.dismiss();
                        this.props.closeLogin();
                        this.setState({
                          isSuccessful: false,
                        });
                      }, 1000);
                    }
                  });
                this.setState({isLoading: false});
              });
    
            }
    
          });
          if (find == false) {
            Alert.alert('Le pseudo ne correspond pas à son adresse email !');
            // it means no username corresponds to this email address
          }
        });
    
      } else {
        console.log('erreur null');
        Alert.alert(
          'Error',
          "login/password don't match!",
        );
       }
      };
    

    ps : i would recommend you to study more javascript and search about promises