user3622460
user3622460

Reputation: 1251

React updating state in two input fields from form submission

I am trying to make a simple contact form using React. Eventually I will send the data collected from the state to a database, but for right now I am trying to just get it to console log the correct values.

Right now, the email field overrides the name field and when I console log both states, name shows up and email is undefined. Here is my React Component

import React, { Component, PropTypes } from 'react';
import ContactData from '../data/ContactData.js';


class FormContact extends Component {
    constructor(props) {
        super(props)
        this.state = {
            name: '',
            email: '',
            textArea: ''
        }
    }

    handleChange(event) {
        event.preventDefault();
        this.setState({
            name: event.target.value,
            email: event.target.email
        })
    }

    handleSubmit(event) {
        event.preventDefault();
        console.log(this.state.name + ' ' + this.state.email);
    }

    render() {
        return (
            <form onSubmit={this.handleSubmit.bind(this)}>
                <label> Name:
                    <input type="text" placeholder="Name" value={this.state.name} onChange={this.handleChange.bind(this)} />
                </label><br />
                <label> Email:
                    <input type="text" placeholder="Email" value={this.state.email} onChange={this.handleChange.bind(this)}/>
                </label><br />
                    <input className="btn btn-primary" type="submit" value="Submit" />
           </form>
        )
    }
}

FormContact.PropTypes = {
    subName: PropTypes.string,
    subEmail: PropTypes.string
}

FormContact.defaultProps = {
    subName: 'Sam',
    subEmail: ''
}

class Contact extends Component {
    render() {
        return (
            <div>
                <h1>CONTACT PAGE</h1>
                <FormContact />
            </div>
        )
    }
}


export default Contact;

Upvotes: 6

Views: 26920

Answers (2)

Boky
Boky

Reputation: 12064

If I understand what you want, you could do it as follows :

  • Add an empty object in your state for the form values

    formValues: {}

  • Add the name attribute to your fields

    <input name="name" .... /> <input name="email" .... />

  • then depending on that name update your state in handleChange function

    let formValues = this.state.formValues;
    let name = event.target.name; // Field name
    let value = event.target.value; // Field value
    
    formValues[name] = value;
    
    this.setState({formValues})
    
  • And if the values go one level deeper, you could use value={this.state.formValues["name"]} instead of value={this.state.name} - where name is the value of the name attribute of your input field

Thus, everything together should be as follows :

class Test extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            formValues: {}
        }
    }

    handleChange(event) {
        event.preventDefault();
        let formValues = this.state.formValues;
        let name = event.target.name;
        let value = event.target.value;

        formValues[name] = value;

        this.setState({formValues})
    }

    handleSubmit(event) {
        event.preventDefault();
        console.log(this.state.formValues);
    }

        render(){
        return (
        <form onSubmit={this.handleSubmit.bind(this)}>
                <label> Name:
                    <input type="text" name="name" placeholder="Name" value={this.state.formValues["name"]} onChange={this.handleChange.bind(this)} />
                </label><br />
                <label> Email:
                    <input type="text" name="email" placeholder="Email" value={this.state.formValues["email"]} onChange={this.handleChange.bind(this)}/>
                </label><br />
                    <input className="btn btn-primary" type="submit" value="Submit" />
           </form>
      )
    }
}

React.render(<Test />, document.getElementById('container'));

Here is fiddle.

Hope this helps.

Upvotes: 19

Pineda
Pineda

Reputation: 7593

The reference to event.target.email does not exist on the event element. The value of a text input from an inline-event handler would be event.target.value for both email and name. The quick solution is to create a separate handler for each input:

handleChangeName(event) { 
  event.preventDefault();
  this.setState({ name: event.target.value });  //<-- both use the same reference
}                                               //    to get the contextual value
handleChangeEmail(event) {                      //    from the inputs v
  event.preventDefault();                       //                    |
  this.setState({ email: event.target.value }); //<--------------------
}

Upvotes: 1

Related Questions