2016-08-05 93 views
2

在下面的代碼(在auth_shared.js),我有一個Loading組分,我希望顯示時的承諾signInWithEmailAndPassword()createUserWithEmailAndPassword()被稱爲顯示加載屏幕組件(每當用戶點擊「登錄」或「註冊」按鈕)。陣營原住民 - 在一個Javascript無極

爲此,我認爲最好創建一個名爲isLoading的狀態,並將其初始設置爲false。在render()中,然後檢查isLoading的值,並確定是否應加載Loading組件或登錄或註冊字段。如果signInWithEmailAndPassword()被調用,則我設置isLoading = true以嘗試顯示Loading組件,而承諾驗證用戶emailpassword。但是,這似乎並沒有工作,我不知道爲什麼!有人可以提供一些見解嗎?謝謝。這裏是我的代碼:

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

回答

2

在你的構造函數,你應該設置isLoadingfalse

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

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

每當你想顯示加載的指標,你應該改變isLoading到異步調用之前true,不在回調中。

您應該只通過setState改變狀態(參見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

我給這是一個嘗試,現在當我點擊「登錄我!」按鈕,「加載」組件不顯示。我認爲這是因爲即使'isLoading = true','render()'不會被再次調用,並且'if'檢查不會發生以確定'Loading'組件應該顯示。你有解決方案或建議如何解決這個問題?感謝您的幫助btw! – szier

+0

@szier嘗試最新的更新,問題可能是因爲你試圖直接改變狀態,而不是使用'setState' – FuzzyTree

+0

工作!只是將其標記爲答案。謝謝! – szier

相關問題