2016-08-05 69 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

相关问题