繁体   English   中英

React Native-在Javascript承诺中显示加载屏幕组件

[英]React Native - Displaying a Loading Screen Component in a Javascript Promise

在下面的代码中(在auth_shared.js中 ),我希望在调用promises signInWithEmailAndPassword()createUserWithEmailAndPassword() (无论用户何时signInWithEmailAndPassword() “登录”或“注册”按钮)都希望显示一个Loading组件。 。

为此,我认为最好创建一个名为isLoading的状态并将其初始设置为false 然后,在render() ,我检查isLoading的值并确定是否应该加载Loading组件或“登录”或“注册”字段。 如果signInWithEmailAndPassword()则设置isLoading = true ,以在诺言正在验证用户的emailpassword同时尝试显示Loading组件。 但是,这似乎不起作用,我不确定为什么! 有人可以对此提供一些见解吗? 谢谢。 这是我的代码:

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上)将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;
        }
      });
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM