javascript - React Native - 在 Javascript Promise 中显示加载屏幕组件

标签 javascript reactjs firebase react-native

在下面的代码中(在 auth_shared.js 中),我有一个 Loading 组件,我希望在 promise signInWithEmailAndPassword()createUserWithEmailAndPassword() 被调用(每当用户点击“登录”或“注册”按钮时)。

为此,我认为最好创建一个名为 isLoading 的状态并将其初始设置为 false。在 render() 中,我然后检查 isLoading 的值并确定我是否应该加载 Loading 组件或登录或注册字段.如果 signInWithEmailAndPassword() 被调用,我会设置 isLoading = true 以尝试在 promise 验证用户时显示 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>
    );
  }
}

登录.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;
        }
      });
  }

关于javascript - React Native - 在 Javascript Promise 中显示加载屏幕组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38780554/

相关文章:

Firebase 动态链接 : Increase Custom Domain Limit

javascript - 无法通过将文档名称保存在对话流上下文中来向文档添加多个字段

javascript - 外部脚本加载后运行Vue组件的方法

javascript - 如何通过插入数字并将后面的数字向右移动来添加到 Javascript 数组中

reactjs - transform-react-jsx 中的 "pragma h"是什么?

javascript - React 不替换 div 中的内容

javascript - 更改 firebase 中的 key 的最佳方法是什么?

javascript - 安装 visual Studio 2015 社区版后,Crystal Reports 13 bobj is undefined JavaScript 错误

javascript - 在 d3 轴上显示持续时间

javascript - 单击React js循环中的第一个元素