React form, to submit object which is then pushed to array

I’m new to React and unsure about how to do this.

I have an array of objects that I have mapped through and rendered in my view. What I want to do is set up a form that will submit the values of each field to the corresponding properties of a new object, but I’m not sure how to go about doing this.

Here is my initial data, which is rendered in the view:

contactArray = [
  {
    name: 'John'
    email: '<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f892979096b89d95999194d69b9795">[email protected]</a>'
    number: 111-111-111
  },
  {
    name: 'Dave'
    email: '<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="97f3f6e1f2d7f2faf6fefbb9f4f8fa">[email protected]</a>'
    phone: '222-222-222'
  }
]

Then I have a form:
class InputForm extends Component {
  render() {
    return (   
        <form>
          <input type='text' onChange={this.handleChange}/>
          <input type='text' onChange={this.handleChange}/>
          <input type='text' onChange={this.handleChange}/>
          <button type='submit' onSubmit={this.handleSubmit}>SUBMIT</button>
        </form>
    ) 
  }

Then I assume I declare the state as this:
constructor(props) {
  super(props);
  this.state = {
    name: '',
    email: '',
    phone: ''
  }
}

Then the submission function I don’t really know how to handle…
handleSubmit() {
  // not sure about this...
  this.setState({
    name: // ????
    email: // ????
    phone: // ????
  })
}

And then I want to clear the submit form, as well as the object that is used to push the new object, which is now in the array (I hope that makes sense…)

So, I’m not even sure how to use state in this scenario, but ultimately I want to push() the new object to the array that is rendered, with all the properties as they were completed in the form.

Sorry I can’t be more complete with my working up to this point, but would at least appreciate some pointers on this!

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

From what I understand you want to push new people to the existing contactArray ? I will share with my way of doing it. Have a look:

const contactArray = [
{
    name: 'John',
    email: '<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="97fdf8fff9d7f2faf6fefbb9f4f8fa">[email protected]</a>',
    phone: '111-111-111'
  },
  {
    name: 'Dave',
    email: '<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e185809784a1848c80888dcf828e8c">[email protected]</a>',
    phone: '222-222-222'
  }
];

class Form extends React.Component {

  constructor() {
    super();
    this.state = {
      contacts: contactArray
    };
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(e) {
    e.preventDefault();
    const
    { contacts } = this.state,
    name = this.refs.name.value,
    email = this.refs.email.value,
    phone = this.refs.phone.value;
    this.setState({
      contacts: [...contacts, {
        name,
        email,
        phone
      }]
    }, () => {
      this.refs.name.value = '';
      this.refs.email.value = '';
      this.refs.phone.value = '';
    });
  }

  render() {
    const { contacts } = this.state;
    console.log('message',this.state.contacts);
    return (   
      <div>
        <h2>Add Someone</h2>
        <form onSubmit={this.handleSubmit}>
          <input type="text" ref="name" placeholder="name" />
          <input type="text" ref="email" placeholder="email" />
          <input type="text" ref="phone" placeholder="phone" />
          <button type="submit">Submit</button>
        </form>
        <h2>Exsiting contacts:</h2>
        <ul>
          {contacts.map((contact) => 
           <li>{`Name: ${contact.name} Email: ${contact.email} Phone: ${contact.phone}`}</li>
          )}
        </ul>
      </div>
    ) 
  }
}

ReactDOM.render(<Form />, document.getElementById('root'));

So first thing we do is save contactArray within our actual component where we are going to use it, next we decalre and bind our handleSubmit I am using refs for the inputs in order to get thier value. this.setState ({ contacts: [...contacts] , { Object }); Here we use the ES6 spread operator to pass all the existing contacts to our new state and add a new contact. { name, email, phone } Is exactly like doing { name:name, email:email ...} It’s just a short-hand, this.setState({}, () => { Callback! }); In the callback function of this.setState({}); I am going to clear the input values. Live demo: http://codepen.io/ilanus/pen/qaXNmb

Here is another way you can do it, same results different approach.

const contactArray = [
  {
    name: 'John',
    email: '<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="701a1f181e30151d11191c5e131f1d">[email protected]</a>',
    phone: '111-111-111'
  },
  {
    name: 'Dave',
    email: '<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f296938497b2979f939b9edc919d9f">[email protected]</a>',
    phone: '222-222-222'
  }
];

class Form extends React.Component {

  constructor() {
    super();
    this.state = {
      contacts: contactArray,
      newContact: {
       name: '',
       email: '',
       phone: ''
     }
    };
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleInput = this.handleInput.bind(this);
  }

  handleSubmit(e) {
    e.preventDefault();
    const { contacts, newContact } = this.state;
    this.setState({
      contacts: [...contacts, newContact],
    }, () => {
      for (let val in newContact) {
        newContact[val] = ''; // Clear the values...
      }
      this.setState({ newContact });
    });
  }

  handleInput(e, element) {
    const { newContact } = this.state;
    newContact[element] = e.target.value;
    this.setState({ newContact });
  }

  render() {
    const { contacts, newContact } = this.state;
    const { name, email, phone } = newContact;
    return (   
      <div>
        <h2>Add Someone</h2>
        <form onSubmit={this.handleSubmit}>
          <input type="text" value={name} onChange={e => this.handleInput(e, 'name')} placeholder="name" />
          <input type="text" value={email} onChange={e => this.handleInput(e, 'email')} placeholder="email" />
          <input type="text" value={phone} onChange={e => this.handleInput(e, 'phone')} placeholder="phone" />
          <button type="submit">Submit</button>
        </form>
        <h2>Exsiting contacts:</h2>
        <ul>
          {contacts.map((contact) => 
           <li>{`Name: ${contact.name} Email: ${contact.email} Phone: ${contact.phone}`}</li>
          )}
        </ul>
      </div>
    ) 
  }
}

ReactDOM.render(<Form />, document.getElementById('root'));

Live demo: http://codepen.io/ilanus/pen/LRjkgx

I highly recommend using the first example. as it’s performance will be better 🙂

Method 2

You don’t need to set state for all the inputs. If you do, it’ll be a problem when you have more input fields. See the below fiddle, in that, I’ve used a single state to store the entire contacts. When you press the submit button, it get all the values from the input and save it to the state. Hope it helps!

Fiddle: http://jsfiddle.net/Pranesh456/8u4uz5xj/1/

[UPDATE]

  1. e.value = null will clear the value inside the form. By this, you’ll able to reset the entire form.
  2. slice() is used to make a copy of the array in the state. As assignment of array is a reference to the original array, any operation on the new array will also reflect in the original array.

Example:

a = [1,2,4]
b = a
b.push(7)
console.log(b) //prints [1,2,4,7]
console.log(a) //also prints [1,2,4,7]

But
b = a.slice() //creates a copy of a
b.push(7)
console.log(b) //prints [1,2,4,7]
console.log(a) //also prints [1,2,4]

More details about slice

By doing this, you’ll not mutate the existing state, which is a good practice.

Hope it help!!


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x