2

I am following a ReactJS tutorial to set up a login form. Semantic ui is used and imported. The email and password are passed into the value attribute inside the form. When this happens, I cannot type anything into the form. As soon as I remove it, I can type information in but I assume it won't get passed into anywhere.

Cannot seem to find this issues anywhere else. Has anyone experienced this issue before?

import React from 'react';
import PropTypes from 'prop-types';
import { Form, Button } from 'semantic-ui-react';
import Validator from 'validator';
import InlineError from '../messages/InlineError';



class LoginForm extends React.Component {
    state = {
        data: {
            email: "",
            password: ""
        },
        loading: false,
        errors: {}
    };

    //... is called spread
    onChange = e => this.setState({
        data: {...this.state.data, [e.target.name]: e.target.value }
    });

    //() means function takes no params
    onSubmit = () => {
        const errors = this.validate(this.state.data);
        this.setState({errors}); //if there are errors, display them
        if(Object.keys(errors).length === 0){
            this.props.submit(this.state.data);
        }
    };

    validate = (data) => {
        const errors = {};
        if(!Validator.isEmail(data.email))
            errors.email = "Invalid email";
        if(!data.password)
            errors.password = "Can't be blank";

        return errors;
    };

    render() {

        const { data, errors } = this.state; // import variables into html
        return (
            <div>
                <Form onSubmit={ this.onSubmit }>
                    <Form.Field error={!!errors.email}>
                        <label htmlFor="email">Email</label>
                        <input type="email"
                               id="email"
                               placeholder="[email protected]"
                               value={ data.email }
                               onChange={ this.onChange }/>
                        {errors.email && <InlineError text={errors.email}/>}
                    </Form.Field>
                    <Form.Field error={!!errors.email}>
                        <label htmlFor="password">Password</label>
                        <input type="password"
                               id="password"
                               value={ data.password }
                               onChange={this.onChange}/>
                        {errors.password && <InlineError text={errors.password}/>}
                    </Form.Field>
                    <Button primary>Login</Button>
                </Form>
            </div>
        );

    }
}

LoginForm.propTypes = {
    submit: PropTypes.func.isRequired
};



export default LoginForm;

tutorial: https://www.youtube.com/watch?v=NO2DaxhoWHk&t=879s

1 Answer 1

6
onChange = e => this.setState({
    data: {...this.state.data, [e.target.name]: e.target.value }
});

This function is setting the state to a variable that shares the name of your input field. Hence e.target.name. But your input fields do not have a name attribute.

You can fix that with:

import React from 'react';
import PropTypes from 'prop-types';
import { Form, Button } from 'semantic-ui-react';
import Validator from 'validator';
import InlineError from '../messages/InlineError';



class LoginForm extends React.Component {
    state = {
        data: {
            email: "",
            password: ""
        },
        loading: false,
        errors: {}
    };

    //... is called spread
    onChange = e => this.setState({
        data: {...this.state.data, [e.target.name]: e.target.value }
    });

    //() means function takes no params
    onSubmit = () => {
        const errors = this.validate(this.state.data);
        this.setState({errors}); //if there are errors, display them
        if(Object.keys(errors).length === 0){
            this.props.submit(this.state.data);
        }
    };

    validate = (data) => {
        const errors = {};
        if(!Validator.isEmail(data.email))
            errors.email = "Invalid email";
        if(!data.password)
            errors.password = "Can't be blank";

        return errors;
    };

    render() {

        const { data, errors } = this.state; // import variables into html
        return (
            <div>
                <Form onSubmit={ this.onSubmit }>
                    <Form.Field error={!!errors.email}>
                        <label htmlFor="email">Email</label>
                        <input type="email"
                               id="email"
                               name="email"
                               placeholder="[email protected]"
                               value={ data.email }
                               onChange={ this.onChange }/>
                        {errors.email && <InlineError text={errors.email}/>}
                    </Form.Field>
                    <Form.Field error={!!errors.email}>
                        <label htmlFor="password">Password</label>
                        <input type="password"
                               id="password"
                               name="password"
                               value={ data.password }
                               onChange={this.onChange}/>
                        {errors.password && <InlineError text={errors.password}/>}
                    </Form.Field>
                    <Button primary>Login</Button>
                </Form>
            </div>
        );

    }
}

LoginForm.propTypes = {
    submit: PropTypes.func.isRequired
};



export default LoginForm;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.