I have a react app, I am trying to perform login using redux and PHP.
I have a component, the component contains a form. the user enters the password and email to the form. after submitting the form the data enter an async-await function called handleSubmit. That function has another function called onSubmitLogin in the await.
from the onSubmit this goes to the actiOn creator in ajax.js file. the next step is the API PHP code, in there the PHP function checks if the user exists. now from there to the reducer and back to function via mapStateToProps,
I want the states notActiveUserError and UserDoesNotExist to change depending on the props (this.props.auth) value I receive from the reducer using the checkUserValidation function.
The problem I have is that the props change but the state is not changing on the first run, every other time it works amazing but it never works on the first time after page loads.
Any help would be great.
this is the code I have: handleSubmit is in LoginForm.js (full component is at the bottom of the question)
handleSubmit = async (event) => { await this.onSubmitLogin(event); this.checkUserValidation(); } onSubmitLogin is in LoginForm.js (full component is at the bottom of the question)
onSubmitLogin(event){ event.preventDefault(); if(this.clientValidate()){ this.clientValidate(); }else{ let userData ={ email: this.state.email, password: this.state.password } this.props.userLogin(userData); } } the action creator
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); }); } } LoginForm component:
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);