简体   繁体   中英

How to know the state of input/form fields of reactstrap form?

I want to make a validation on my fields of reactstrap form. How do I know the state of fields like pristine, dirty etc. How do make field's error visible only after the field has been touched and not when the component first render.

The code is working fine as per my expectation except the fact the the fields shows the error on first render which I couldn't accomplish after long try.

import. React, { Component } from 'react';
import { Link } from 'react-router-dom';
import GoogleLogin from 'react-google-login';
import axios from 'axios';
import { connect } from 'react-redux';
import { loginUser } from '../../actions/authActions';
import PropTypes from 'prop-types';

import API_ROOT from '../../Api';
// import './Login.css';
import { FormErrors } from '../FormErrors';
import {
    Button,
    Card, CardBody,
    CardGroup, Col,
    FormFeedback,
    Container, Form,
    Input, InputGroup,
    InputGroupAddon, InputGroupText,
    Row
} from 'reactstrap';
const responseGoogle = (response) => {
    console.log(response);
}
class Login extends Component {
    constructor(props) {
        super(props);
        this.state = {
            isLoading: false,
            email: "",
            password: "",
            formErrors: { email: '', password: '' },
            emailValid: false,
            passwordValid: false,
            formValid: false
        };
    }

    componentDidMount() {
        console.log("login props", this.props)
        if (this.props.auth.isAuthenticated) {
            this.props.history.push('/dashboard');
        }
    }
    componentWillReceiveProps(nextProps) {
        if (nextProps.auth.isAuthenticated) {
            this.props.history.push('/dashboard');
        }
        if (nextProps.errors) {
            this.setState({ errors: nextProps.errors });
        }
    }
    onChange = (e) => {
        this.handleUserInput(e)
    }
    handleUserInput(e) {
        const name = e.target.name;
        const value = e.target.value;
        this.setState({ [name]: value },
            () => { this.validateField(name, value) });
        console.log("handle user input", this.state)
    }
    validateField(fieldName, value) {
        let fieldValidationErrors = this.state.formErrors;
        let emailValid = this.state.emailValid;
        let passwordValid = this.state.passwordValid;
        console.log("validationfiled ", this.state)

        switch (fieldName) {
            case 'email':
                emailValid = value.match(/^([\w.%+-]+)@([\w-]+\.)+([\w]{2,})$/i);
                fieldValidationErrors.email = emailValid ? '' : ' is invalid';
                break;
            case 'password':
                passwordValid = value.length >= 6;
                fieldValidationErrors.password = passwordValid ? '' : ' is too short';
                break;
            default:
                break;
        }
        this.setState({
            formErrors: fieldValidationErrors,
            emailValid: emailValid,
            passwordValid: passwordValid
        }, this.validateForm);
    }

    validateForm() {
        this.setState({ formValid: this.state.emailValid && this.state.passwordValid });
    }
    errorClass(error) {
        return (error.length === 0 ? '' : 'has-error');
    }

    onSubmit = (e) => {
        e.preventDefault();
        console.log(e)
        const userData = {
            email: this.state.email,
            password: this.state.password
        };
        console.log(userData)

        this.props.loginUser(userData);
    }
Input
    render() {
        console.log(Form.Input)
        return (
            <div className="app flex-row align-items-center">
                <Container>
                    <Row className="justify-content-center">
                        <Col md="8">
                            <CardGroup>
                                <Card className="p-4">
                                    <CardBody>
                                        <Form onSubmit={this.onSubmit}  >
                                            <h1>Login</h1>
                                            <p className="text-muted">Sign In to your account</p>
                                            <InputGroup className="mb-3">
                                                <InputGroupAddon addonType="prepend">
                                                    <InputGroupText>
                                                        <i className="icon-user"></i>
                                                    </InputGroupText>
                                                </InputGroupAddon>
                                                <Input invalid={!this.state.emailValid} type="text" name="email" value={this.state.email} placeholder="Username" onChange={this.onChange} />
                                                <FormFeedback>Valid Email is required  </FormFeedback>
                                            </InputGroup>
                                            <InputGroup className="mb-4">
                                                <InputGroupAddon addonType="prepend">
                                                    <InputGroupText>
                                                        <i className="icon-lock"></i>
                                                    </InputGroupText>
                                                </InputGroupAddon>
                                                <Input invalid={!this.state.passwordValid} type="password" name="password" value={this.state.password} placeholder="Password" onChange={this.onChange}  />
                                                <FormFeedback>Password of at least 6 character is Required</FormFeedback>
                                            </InputGroup>
                                            <Row>
                                                <Col xs="6">
                                                    <Button color="primary" className="px-4">Login</Button>
                                                </Col>
                                                <Link to="/forgotpassword">
                                                    <Col xs="6" className="text-right">
                                                        <Button color="link" className="px-0">Forgot password?</Button>
                                                    </Col>
                                                </Link>
                                            </Row>
                                        </Form>
                                    </CardBody>
                                </Card>
                                <Card className="text-white bg-primary py-5 d-md-down-none" style={{ width: '44%' }}>
                                    <CardBody className="text-center">
                                        <div>
                                            <h2>Sign up</h2>
                                            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut
                          labore et dolore magna aliqua.</p>
                                            <Link to="/signup">
                                                <Button color="primary" className="mt-3" active tabIndex={-1}>Register Now!</Button>
                                            </Link>
                                        </div>
                                    </CardBody>
                                </Card>
                            </CardGroup>
                        </Col>
                    </Row>
                </Container>
            </div>
        );
    }
}

Login.propTypes = {
    loginUser: PropTypes.func.isRequired,
    auth: PropTypes.object.isRequired,
    errors: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
    auth: state.auth,
    errors: state.errors
});

export default connect(mapStateToProps, { loginUser })(Login)

I realize this is a really old question, but i was having the same trouble and thought I would post my solution in case it would be helpful to someone else.

Everything is exactly the same as the code posted in the original question, except the initial values of the validity fields (this.state.emailValid, this.state.passwordValid, etc...) should be equal to true.

The onChange handler should be able to tell us if the field has been touched so that in conjunction with the initial value of those fields should give us what we are looking for.

From this:

  this.state = {
    isLoading: false,
    email: "",
    password: "",
    formErrors: { email: '', password: '' },
    emailValid: false,
    passwordValid: false,
    formValid: false
  };

To this:

  this.state = {
    isLoading: false,
    email: "",
    password: "",
    formErrors: { email: '', password: '' },
    emailValid: true,
    passwordValid: true,
    formValid: true
  };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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