Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
like image 766
user3622460 Avatar asked Dec 08 '16 00:12

user3622460


People also ask

How does react handle multiple state updates?

Setting state does not change the variable in the existing render, but it requests a new render. React processes state updates after event handlers have finished running. This is called batching. To update some state multiple times in one event, you can use setNumber(n => n + 1) updater function.

How do I update my state data in react?

To update our state, we use this. setState() and pass in an object. This object will get merged with the current state. When the state has been updated, our component re-renders automatically.


2 Answers

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.

like image 171
Boky Avatar answered Oct 01 '22 21:10

Boky


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 }); //<--------------------
}
like image 32
Pineda Avatar answered Oct 01 '22 22:10

Pineda