显示加载动画点击登录按钮时不工作

问题描述 投票:0回答:1

我有下面的代码。我有两个问题。第一个,当我点击登录按钮显示加载动画。但是,应该如果登录过程是成功还是失败的切换。它不工作。第二个,如果我不添加这行代码“this.toggleLoader = this.toggleLoader.bind(本);”,则toggleLoader功能显示错误,this.setState不是函数。请无法登录,经过成功,页面导航到新的屏幕主页。我如何可以切换之前加载器?如果我在,如果循环之后调用函数toggleLoader(),没有工作。

import React, {Component} from 'react'
import {
Alert,
AsyncStorage,
Keyboard,
Text,
View,
TextInput,
TouchableHighlight, TouchableOpacity,
Image,
ActivityIndicator,
} from 'react-native'
import config from "../../../../config";
import styles from './style'
import {Icon} from "react-native-elements";

class Login extends Component {

constructor(props) {
    super(props);
    this.state = {
        credentials: {
            email: "",
            password: "",
        },
        loading: false,
    };
    this.toggleLoader = this.toggleLoader.bind(this);
}

updateText(text, field) {
    let newCredentials = Object.assign(this.state.credentials);
    newCredentials[field] = text;
    this.setState = ({
        credentials: newCredentials
    })
}

toggleLoader() {
    this.setState({
        loading: !this.state.loading
    });
}

async login() {
    Keyboard.dismiss();
    let credentials = this.state.credentials;
    if (this.state.credentials.email == '' || this.state.credentials.password == '') {
        Alert.alert("Please fill all the fields.");
    } else {

            const that = this;
            credentials.email = that.state.credentials.email.toLowerCase();
            // start loading when all fields are fill
             this.setState({ loading: !this.state.loading });

            fetch(config.baseURL + 'mobileapi/get_token/?username=' + `${that.state.credentials.email}` + '&password=' + `${that.state.credentials.password}`, {
                method: 'POST',
                headers: {
                    Accept: 'application/json',
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    credentials: credentials,
                }),
            })
                .then((response) => response.json())
                .then(responseJson => {
                    //stop loading after successful response
                    this.setState({ loading: !this.state.loading });

                    if (responseJson.confirmation === "success") {
                       // alert(JSON.stringify(responseJson.data));
                        AsyncStorage.setItem('USER_ID', responseJson.data.user_id);
                        AsyncStorage.setItem('USER_NAME', responseJson.data.user_name);
                        AsyncStorage.setItem('USER_TYPE', responseJson.data.user_type);
                        AsyncStorage.setItem('FIRST_NAME', responseJson.data.first_name);
                        AsyncStorage.setItem('LAST_NAME', responseJson.data.last_name);
                        AsyncStorage.setItem('EMAIL', responseJson.data.user_email);
                        AsyncStorage.setItem('AUTHENTICATION_TOKEN', responseJson.data.token);

                        setTimeout(() => {
                            this.props.navigation.navigate("Home")
                        }, 500);

                    } else {


                        setTimeout(() => {
                            //code to handle an error
                            throw new Error(responseJson.message);
                        }, 500);

                    }
                })
                .catch((err) => {

                    //stop loading
                    this.setState({ loading: !this.state.loading });

                    setTimeout(() => {
                        if (JSON.stringify(err.message) === JSON.stringify('Network request failed')) {
                            alert('Please check your internet connection or try again later');
                        } else {
                            alert(JSON.stringify(err.message));
                        }
                    }, 500);

                })

    }
}

render() {
    const loginText = (this.state.loader) ? 'Loading' : 'Login';
    return (
        <View style={styles.container}>
            <Image source={require('../../../../assets/images/icons/logo.png')}
                   style={{width: 99, height: 99, margin: 5,}}/>
            <Text style={{fontSize: 20, margin: 20, color: "#0aa1e2"}}>Test App</Text>
            <View style={styles.inputContainer}>
                <Image style={styles.inputIcon}
                       source={require('../../../../assets/images/icons/username.png')}/>
                <TextInput style={styles.inputs}
                           placeholder="Username"
                           keyboardType="email-address"
                           underlineColorAndroid='transparent'
                           onChangeText={text => {
                               this.updateText(text, 'email')
                           }} value={this.state.email}
                           autoCorrect={false}
                           autoCapitalize={"none"}
                />
            </View>
            <View style={styles.inputContainer}>
                <Image style={styles.inputIcon}
                       source={require('../../../../assets/images/icons/password.png')}/>
                <TextInput style={styles.inputs}
                           placeholder="Password"
                           secureTextEntry={true}
                           underlineColorAndroid='transparent'
                           onChangeText={text => {
                               this.updateText(text, 'password')
                           }}
                           value={this.state.password}
                           autoCorrect={false}
                           secureTextEntry/>
            </View>
            <TouchableHighlight style={[styles.buttonContainer, styles.loginButton]}
                                onPress={this.login.bind(this)} >
                <View style={{justifyContent: 'center', flex: 1, flexDirection: 'row'}}>
                    {this.state.loading === false ?
                        <Icon name='login' type='entypo' size={16} color='white'/> :
                        <ActivityIndicator size="small" color="#ffffff"/>}
                    <Text style={styles.loginText}> {loginText} </Text>
                </View>
            </TouchableHighlight>
        </View>
    );
}
}

export default Login;
react-native
1个回答
1
投票

我已经更新您的login()方法。请您尝试一下。它可以帮助你。

 async login() {
        Keyboard.dismiss();
        let credentials = this.state.credentials;
        if (this.state.credentials.email == '' || this.state.credentials.password == '') {
            Alert.alert("Please fill all the fields.");
        } else {
            credentials.email = that.state.credentials.email.toLowerCase();
            // start loading when all fields are fill
            this.toggleLoader();
            fetch(config.baseURL + 'mobileapi/get_token/?username=' + `${that.state.credentials.email}` + '&password=' + `${that.state.credentials.password}`, {
                method: 'POST',
                headers: {
                    Accept: 'application/json',
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    credentials: credentials,
                }),
            })
                .then((response) => response.json())
                .then(responseJson => {
                      //stop loading after successful response
                        this.toggleLoader();
                    if (responseJson.confirmation === "success") {
                        AsyncStorage.setItem('USER_ID', responseJson.data.user_id);
                        AsyncStorage.setItem('USER_NAME', responseJson.data.user_name);
                        AsyncStorage.setItem('USER_TYPE', responseJson.data.user_email);
                        AsyncStorage.setItem('AUTHENTICATION_TOKEN', responseJson.data.token);
                        setTimeout(() => {
                            this.props.navigation.navigate("Home")
                        }, 500);
                    } else {
                        setTimeout(() => {
                            //code to handle an error
                        }, 500);
                    }
                })
                .catch((err) => {
                    //stop loading
                    this.toggleLoader();
                    setTimeout(() => {
                        if (JSON.stringify(err.message) === JSON.stringify('Network request failed')) {
                            alert('Please check your internet connection or try again later');
                        } else {
                            alert(JSON.stringify(err.message));
                        }
                    }, 500);
                })
        }
    }

你已经在类似的TextInput设置this.state.email电子邮件。这应该是this.state.credentials.email。同样的事情sholud是遵循密码。改变)渲染onPress事件(方法是这样的:

   render() {
    const loginText = (this.state.loader) ? 'Loading' : 'Login';
    return (
        <View style={styles.container}>
            <Image source={require('../../../../assets/images/icons/logo.png')}
                   style={{width: 99, height: 99, margin: 5,}}/>
            <Text style={{fontSize: 20, margin: 20, color: "#0aa1e2"}}>Test App</Text>
            <View style={styles.inputContainer}>
                <Image style={styles.inputIcon}
                       source={require('../../../../assets/images/icons/username.png')}/>
                <TextInput style={styles.inputs}
                           placeholder="Username"
                           keyboardType="email-address"
                           underlineColorAndroid='transparent'
                           onChangeText={text => {
                               this.updateText(text, 'email')
                           }} 
                           value={this.state.credentials.email}
                           autoCorrect={false}
                           autoCapitalize={"none"}
                />
            </View>
            <View style={styles.inputContainer}>
                <Image style={styles.inputIcon}
                       source={require('../../../../assets/images/icons/password.png')}/>
                <TextInput style={styles.inputs}
                           placeholder="Password"
                           secureTextEntry={true}
                           underlineColorAndroid='transparent'
                           onChangeText={text => {
                               this.updateText(text, 'password')
                           }}
                           value={this.state.credentials.password}
                           autoCorrect={false}
                           secureTextEntry/>
            </View>
            <TouchableHighlight style={[styles.buttonContainer, styles.loginButton]}
                                onPress={this.login.bind(this)} >
                <View style={{justifyContent: 'center', flex: 1, flexDirection: 'row'}}>
                    {this.state.loading === false ?
                        <Icon name='login' type='entypo' size={16} color='white'/> :
                        <ActivityIndicator size="small" color="#ffffff"/>}
                    <Text style={styles.loginText}> {loginText} </Text>
                </View>
            </TouchableHighlight>
        </View>
    );
}

类型错误:this.setState不是一个函数。此误差从UPDATETEXT到来()method.you添加=的setState,这是引发错误时。

updateText(text, field) {
    let newCredentials = Object.assign(this.state.credentials);
    newCredentials[field] = text;
    // setState should be done like this
    this.setState({
        credentials: newCredentials
    })
}
© www.soinside.com 2019 - 2024. All rights reserved.