2016-08-05 25 views
2

in dem folgenden Code angezeigt (in auth_shared.js), ich habe eine Loading Komponente, die ich wünschte, angezeigt wird, wenn die Versprechungen signInWithEmailAndPassword() oder createUserWithEmailAndPassword() aufgerufen werden (wenn der Benutzer Hits die "Anmelden" oder "Registrieren" Tasten).Reagieren Native - ein Ladebildschirm Komponente in einem Javascript-Versprechen

Um dies zu tun, dachte ich, es wäre am besten, einen Zustand mit dem Namen isLoading zu erstellen und zunächst auf false zu setzen. In render() überprüfe ich dann den Wert isLoading und stelle fest, ob ich die Loading Komponente oder die Felder Anmelden oder Registrieren laden soll. Wenn signInWithEmailAndPassword() aufgerufen wird, dann setze ich isLoading = true in einem Versuch, die Loading Komponente anzuzeigen, während das Versprechen die Benutzer email und password validiert. Dies scheint jedoch nicht zu funktionieren und ich bin mir nicht sicher warum! Kann mir bitte jemand einen Einblick geben? Vielen Dank. Hier ist mein Code:

loading.js

import React, { Component } from 'react'; 
import { 
    ActivityIndicator, 
    Text, 
    View 
} from 'react-native'; 

import styles from 'TextbookSwap/app_styles'; 

export default class Loading extends Component { 
    render() { 
    return (
     <View style={styles.loadingBG}> 
     <ActivityIndicator 
      animating={true} 
      color="white" 
      size="large" 
      style={{margin: 15}} 
     /> 

     <Text style={styles.loadingText}> 
      {this.props.loadingText} 
     </Text> 
     </View> 
    ); 
    } 
} 

login.js

import React, { Component } from 'react'; 

// Components 
import AuthShared from '../auth_shared'; 

export default class Login extends Component { 

    render() { 
    return (
     <AuthShared login={true}/> 
    ); 
    } 
} 

signup.js

import React, { Component } from 'react'; 

// Components 
import AuthShared from '../auth_shared'; 

export default class SignUp extends Component { 

    render() { 
    return (
     <AuthShared login={false}/> 
    ); 
    } 
} 

auth_shared.js

import React, { Component } from 'react'; 
import { 
    AlertIOS, 
    Dimensions, 
    Image, 
    ScrollView, 
    StyleSheet, 
    Text, 
    TextInput, 
    TouchableOpacity, 
    View 
} from 'react-native'; 

import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'; 
import { Actions } from 'react-native-router-flux'; 

import firebaseApp from 'TextbookSwap/firebase_setup'; 
import styles from 'TextbookSwap/app_styles'; 

// Components 
import HeaderImage from './header_image'; 
import Loading from './loading.js'; 

// For Firebase Auth 
const auth = firebaseApp.auth(); 

export default class Login extends Component { 
    constructor(props) { 
    super(props); 

    this.state = { 
     isLoading: true, 
     firstName: '', 
     lastName: '', 
     email: '', 
     password: '', 
     passwordConfirmation: '' 
    } 
    } 

    componentDidMount() { 
    let user = auth.currentUser; 
    if (user) { 
     console.log(msg) 
     Actions.home 
    } else { 
     return; 
    } 
    } 

    render() { 
    if (this.state.isLoading) { 
     return <Loading loadingText="Loading..." /> 
    } else { 
     return (
     <View style={styles.mainContainer}> 
      <KeyboardAwareScrollView 
      style={styles.scrollView} 
      keyboardShouldPersistTaps={false} 
      automaticallyAdjustContentInsets={true} 
      alwaysBonceVertical={false} 
      > 
      <View style={styles.formInputContainer}> 
       <HeaderImage /> 
       {this.props.login ? this.renderLogin() : this.renderSignup()} 
      </View> 

      {this.props.login ? this.renderFooter() : null} 

      </KeyboardAwareScrollView> 
     </View> 
    ); 
    } 
    } 

    renderLogin() { 
    return (
     <View> 
     {this.renderEmailAndPasswordForms()} 
     <View style={styles.authButtonContainer}> 
      <TouchableOpacity 
      style={styles.authButton} 
      onPress={this._logInUser.bind(this)} 
      > 
      <Text style={styles.actionText}>Log me in!</Text> 
      </TouchableOpacity> 
     </View> 
     </View> 
    ); 
    } 

    renderSignup() { 
    return (
     <View> 
     <View style={[styles.formInputWrapper, styles.formInputInlineWrapper]}> 
      <View style={{borderColor: '#50514F', borderLeftWidth: 0, borderRightWidth: 0.5, borderTopWidth: 0, borderBottomWidth: 0}}> 
      <TextInput 
       style={[styles.formInput, styles.formInputInline]} 
       autoFocus={true} 
       autoCapitalize="none" 
       autoCorrect={false} 
       placeholder="First Name" 
       onChangeText={(firstName) => this.setState({firstName})} 
      /> 
      </View> 

      <TextInput 
      style={[styles.formInput, styles.formInputInline]} 
      autoFocus={true} 
      autoCapitalize="none" 
      autoCorrect={false} 
      placeholder="Last Name" 
      onChangeText={(lastName) => this.setState({lastName})} 
      /> 
     </View> 
     {this.renderEmailAndPasswordForms()} 

     <View style={styles.formInputWrapper}> 
      <TextInput 
      style={styles.formInput} 
      secureTextEntry={true} 
      autoCapitalize="none" 
      autoCorrect={false} 
      placeholder="Password Confirmation" 
      onChangeText={(passwordConfirmation) => this.setState({passwordConfirmation})} 
      /> 
     </View> 

     <View style={styles.authButtonContainer}> 
      <TouchableOpacity 
      style={styles.authButton} 
      onPress={this._signUpUser.bind(this)} 
      > 
      <Text style={styles.actionText}>Sign me up!</Text> 
      </TouchableOpacity> 
     </View> 
     </View> 
    ); 
    } 

    renderEmailAndPasswordForms() { 
    return (
     <View> 
     <View style={styles.formInputWrapper}> 
      <TextInput 
      style={styles.formInput} 
      autoFocus={true} 
      autoCapitalize="none" 
      autoCorrect={false} 
      placeholder="Email" 
      onChangeText={(email) => this.setState({email})} 
      /> 
     </View> 

     <View style={styles.formInputWrapper}> 
      <TextInput 
      style={styles.formInput} 
      secureTextEntry={true} 
      autoCapitalize="none" 
      autoCorrect={false} 
      placeholder="Password" 
      onChangeText={(password) => this.setState({password})} 
      /> 
     </View> 

     </View> 
    ); 
    } 

    renderFooter() { 
    return (
     <View style={styles.footer}> 
     <TouchableOpacity 
      style={styles.footerButton} 
      onPress={Actions.signup} 
     > 
      <Text style={styles.actionText}>No account? Create one!</Text> 
     </TouchableOpacity> 
     </View> 
    ); 
    } 

    _logInUser() { 
    let { isLoading, email, password } = this.state; 

    auth.signInWithEmailAndPassword(email, password) 
     .then(() => { 
     isLoading = true; 
     Actions.home; 
     isLoading = false; 
     }) 
     .catch((error) => { 
     isLoading = false; 
     switch(error.code) { 
      case "auth/wrong-password": 
      AlertIOS.alert('Uh oh!', 'Invalid password! Please try again.'); 
      break; 

      case "auth/invalid-email": 
      AlertIOS.alert('Uh oh!', 'Invalid email! Please try again.'); 
      break; 

      case "auth/user-not-found": 
      AlertIOS.alert('Uh oh!', 'Please check your credentials and try again'); 
      break; 
     } 
     }); 
    } 

    _signUpUser() { 
    let { firstName, lastName, email, password, passwordConfirmation } = this.state; 
    // Check that email, password, and passwordConfirmation are present 
    if (!firstName || !lastName || !email || !password || !passwordConfirmation) { 
     AlertIOS.alert('Uh oh!', 'Please fill out all fields'); 

    } else if (password == passwordConfirmation) { 

     auth.createUserWithEmailAndPassword(email, password) 
     .then((user) => { 
      user.updateProfile({ 
      displayName: `${firstName} ${lastName}` 
      }) 
      .then(Actions.home) 
      .catch((error) => { 
      AlertIOS.alert(`${error.code}`, `${error.message}`); 
      }); 
     }) 
     .catch((error) => { 
      AlertIOS.alert(`${error.code}`, `${error.message}`); 
     }); 

    } else { 
     AlertIOS.alert('Uh oh!', 'Passwords do not match'); 
    } 
    } 
} 

Antwort

2

In Ihrem Konstruktor sollten Sie setzen isLoading zu false

export default class Login extends Component { 
    constructor(props) { 
    super(props); 

    this.state = { 
     isLoading: true, // change this to false 

Wenn Sie die Ladeanzeige angezeigt werden soll, können Sie isLoading zu truevor der Asynchron-Aufruf ändern sollte, nicht auf dem Rückruf.

Sie sollten nur den Zustand über setState ändern (siehe https://facebook.github.io/react/docs/component-api.html)

_logInUser() { 
    let { isLoading, email, password } = this.state; 
    this.setState({isLoading:true}); // move state change here 
    auth.signInWithEmailAndPassword(email, password) 
     .then(() => {   
     Actions.home; 
     this.setState({isLoading:false}); // use setState 
     }) 
     .catch((error) => { 
     this.setState({isLoading:false}); // use setState 
     switch(error.code) { 
      case "auth/wrong-password": 
      AlertIOS.alert('Uh oh!', 'Invalid password! Please try again.'); 
      break; 

      case "auth/invalid-email": 
      AlertIOS.alert('Uh oh!', 'Invalid email! Please try again.'); 
      break; 

      case "auth/user-not-found": 
      AlertIOS.alert('Uh oh!', 'Please check your credentials and try again'); 
      break; 
     } 
     }); 
    } 
+0

Ich gab diesem einen Versuch und wenn ich jetzt die Hit „in Anmelden me!“ Schaltfläche wird die 'Loading'-Komponente nicht angezeigt. Ich denke, dies liegt an der Tatsache, dass, obwohl 'isLoading = true', 'render()' nicht erneut aufgerufen wird und die 'if'-Prüfung nicht stattfindet, um zu bestimmen, ob die 'Loading'-Komponente ist oder nicht sollte angezeigt werden. Hast du eine Lösung oder einen Ratschlag, wie ich das lösen kann? Danke für deine Hilfe übrigens! – szier

+0

@szier versuchen Sie das neueste Update, das Problem kann sein, weil Sie versuchen, den Zustand direkt anstelle von 'setState' ändern – FuzzyTree

+0

Das hat funktioniert! Habe das nur als Antwort markiert. Vielen Dank! – szier