在下面的代码中(在auth_shared.js中),我有一个Loading组件,我希望在调用promises signInWithEmailAndPassword()或createUserWithEmailAndPassword()时显示(每当用户点击“登录”或“注册”按钮时) . 为此,我认为
为此,我认为最好创建一个名为isLoading的状态,并在最初将其设置为false.在render()中,然后检查isLoading的值并确定是否应加载“加载”组件或“登录”或“注册”字段.如果调用signInWithEmailAndPassword(),则在承诺验证用户电子邮件和密码时,设置isLoading = true以尝试显示“加载”组件.但是,这似乎不起作用,我不知道为什么!有人可以提供一些见解吗?谢谢.这是我的代码:
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'); } } }在构造函数中,您应该将isLoading设置为false
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; } }); }