繁体   English   中英

reactjs async / await 在第一次运行时不起作用

[英]reactjs async / await doesn't work in first run

我有一个反应应用程序,我正在尝试使用 redux 和 PHP 执行登录。

我有一个组件,该组件包含一个表单。 用户在表单中输入密码和 email。 提交表单后,数据输入一个名为handleSubmit 那个 function 有另一个 function 在等待中调用onSubmitLogin

onSubmitactiOn creator文件中的ajax.js创建者。 下一步是 API PHP 代码,其中 PHP ZC1C425268E68385D1AB5074C 检查用户是否存在。 现在从那里到减速器,然后通过 mapStateToProps 返回mapStateToProps

我希望状态notActiveUserErrorUserDoesNotExist根据我使用checkUserValidation function 从减速器收到的道具( this.props.auth )值而改变。

我遇到的问题是道具发生了变化,但 state 在第一次运行时没有变化,每隔一次它就工作得很好,但在页面加载后的第一次它就永远不会工作。

任何帮助都会很棒。

这是我的代码: handleSubmit在 LoginForm.js 中(完整的组件在问题的底部)

handleSubmit = async (event) => { 
    await this.onSubmitLogin(event);
    this.checkUserValidation();
}

onSubmitLogin在 LoginForm.js 中(完整的组件在问题的底部)

onSubmitLogin(event){
    event.preventDefault();

    if(this.clientValidate()){
        this.clientValidate();
    }else{
        let userData ={
            email: this.state.email,
            password: this.state.password
        }
        this.props.userLogin(userData);
    }
}

动作创造者

export const userLogin = (userData) => {
    return (dispatch) => {
        axios({
                url: `${API_PATH}/users/Login.php`,
                method: 'post',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'
                },
                data: JSON.stringify(userData)
            })
            .then(function(response) {
                dispatch({ type: USER_LOGIN, value: response.data });
            })
            .catch(function(error) {
                console.log(error);
            });
    }
}

登录表单组件:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Redirect, Link  } from 'react-router-dom';
import {
    Button,
    Form,
    FormGroup,
    FormControl,
    Col,
    Alert,
    Grid,
    Row
} from 'react-bootstrap';

import { userLogedIn } from '../../actions'; 
import { userLogin } from '../../actions/ajax'; 


class LoginForm extends Component {
    constructor() {
        super();
        this.state={
            email: '',
            username: '',
            password: '',
            auth: false,
            usernameError: '',
            passwordError: '',
            EmptyUsernameError: '',
            EmptyPasswordError: '',
            notActiveUserError: '',
            UserDoesNotExist: '',
            userid: ''
        }
        this.handleSubmit = this.handleSubmit.bind(this);
        this.onChange = this.onChange.bind(this);

    }


    clientValidate = () => {
        let isError = false;

        if(this.state.email === ''){

            this.setState({EmptyUsernameError: 'לא הזנתם דואר אלקטרוני'});
        }
        if(this.state.password === ''){
            isError = true;
            this.setState({EmptyPasswordError: 'לא הזנתם סיסמה'});
        }      
        return isError;
    }

    checkUserValidation(){
        if(this.props.auth === false && this.props.userid !== undefined){
            console.log('this.props 1', this.props);
            this.setState({notActiveUserError: 'חשבון לא מאומת'});
        }
        if(this.props.auth === false && this.props.userid === undefined){
            console.log('this.props 2', this.props);
            this.setState({UserDoesNotExist: 'משתשמ לא קיים'});
        }
    }

    onSubmitLogin(event){
        event.preventDefault();

        if(this.clientValidate()){
            this.clientValidate();
        }else{
            let userData ={
                email: this.state.email,
                password: this.state.password
            }
            this.props.userLogin(userData);
        }
    }

    handleSubmit = async (event) => { 
        await this.onSubmitLogin(event);
        this.checkUserValidation();
    }


    redirectUser = () => {    
        if(this.props.auth === true && this.props.userid != null){
            const timestamp = new Date().getTime(); // current time
            const exp = timestamp + (60 * 60 * 24 * 1000 * 7)                // add one week

            let auth = `auth=${this.props.auth};expires=${exp}`;
            let userid = `userid=${this.props.userid};expires=${exp}`;

            document.cookie = auth;
            document.cookie = userid;

            return <Redirect to='/records/biblist' />
        }
    }


    onChange(event){
        this.setState({
            [event.target.name]: event.target.value,
            auth: false,
            usernameError: '',
            EmptyPasswordError: '',
            EmptyUsernameError: '',
            notActiveUserError: '',
            UserDoesNotExist: ''
        })


    }

    isLoggedIn = () =>{
        console.log(' this.props.auth ',  this.props.auth);

    }

    render() {
        this.isLoggedIn();
        return (

                        <Form>

                            <FormGroup  controlId="formHorizontalusername">
                                <Col xs={12} sm={5} style={TopMarginLoginBtn}>
                                <Row style={marginBottomZero}>
                                    <FormControl ref="email" name="email" type="email" onChange={this.onChange} placeholder="דואר אלקטרוני" aria-label="דואר אלקטרוני"/>
                                </Row>
                                </Col>
                                <Col xs={12} sm={4} style={TopMarginLoginBtn}>
                                <Row style={marginBottomZero}>
                                    <FormControl ref="password" name="password" type="password" onChange={this.onChange} placeholder="הקלד סיסמה" aria-label="סיסמה"/>
                                    </Row>
                                </Col>

                                <Col  xs={12} sm={3} style={TopMarginLoginBtn} >

                                    <Button onClick={this.handleSubmit} type="submit" className="full-width-btn" id="loginSubmit">התחבר</Button>
                                    {this.redirectUser()}
                                    </Col>
                                    <Col xs={12}>
                                    <Link to="/passwordrecovery">שכחתי את הסיסמה</Link>
                                </Col>
                            </FormGroup>
                            {
                                this.state.EmptyUsernameError ? 
                                <Alert bsStyle="danger"> {this.state.EmptyUsernameError} </Alert> :
                                ''
                            }
                            {
                                this.state.EmptyPasswordError ? 
                                <Alert bsStyle="danger"> {this.state.EmptyPasswordError} </Alert> :
                                ''
                            }

                            {
                                this.state.usernameError ? 
                                <Alert bsStyle="danger"> {this.state.usernameError} </Alert> :
                                ''
                            }
                             {
                                 //PROBLEM!! state updates before props
                                 this.state.notActiveUserError ? 
                                <Alert bsStyle="danger">{this.state.notActiveUserError}</Alert> :
                                ''
                            }
                            {
                                //PROBLEM!! state updates before props
                                this.state.UserDoesNotExist ? 
                                <Alert bsStyle="danger">{this.state.UserDoesNotExist} </Alert> :
                                ''
                            }

                            <Row className="show-grid">

                        </Row>
                        </Form>



        );
    }
}
const bold={
    fontWeight: 'bolder'
}
const mapDispatchToProps = dispatch => {
    return {
        userLogedIn: (params) => dispatch(userLogedIn(params))
    };
};


const mapStateToProps = state => {
    return {
        userid: state.authReducer.userid,
        auth: state.authReducer.auth,
        email: state.authReducer.email
    }
}

export default connect(mapStateToProps, {userLogedIn, userLogin})(LoginForm);

如果要在组件中使用 async-await,则必须将 API 调用移动到组件,因为当您从组件调用操作时,它不会将数据返回到组件。

if you want to use redux then I suggest you should remove async-await from your component it won't work, instead use the redux state to store success or failed state and handle that change in your component from getDerivedStateFromProps

export const userLogin = (userData) => {
    return (dispatch) => {
        dispatch({ type: USER_LOGIN_BEGIN }); // reset error/login state
        axios({
                url: `${API_PATH}/users/Login.php`,
                method: 'post',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'
                },
                data: JSON.stringify(userData)
            })
            .then(function(response) {
                dispatch({ type: USER_LOGIN, value: response.data });
            })
            .catch(function(error) {
                dispatch({ type: USER_LOGIN_FAILED, value: error });
            });
    }
}

在你的组件中

onSubmitLogin(event){
    event.preventDefault();
    if(!this.clientValidate()){
        let userData ={
            email: this.state.email,
            password: this.state.password
        }
        this.props.userLogin(userData);
    }
}

handleSubmit = (event) => { 
    this.onSubmitLogin(event);
  // this.checkUserValidation // move this logic to reducer and set error there according to response
}

static getDerivedStateFromProps(nextProps, prevState) {
  // handle success/error according to your need and return update state
}

暂无
暂无

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

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