簡體   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