Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: update state with form data onChange using the spread operator

I'm trying to update my state using the spread operator so I can pass form data in a http request, but it doesn't seem to be updating at all from what i can see in my console.logs.

I'm also getting the error 'TypeError: Invalid attempt to spread non-iterable instance'. I need the data I pass in to be an object though.

import React from 'react'
import SuperAgent from 'superagent'
import { string } from 'prop-types'

class ContactForm extends React.Component {
  constructor(props) {
    super(props)

    this.handleClick = this.handleClick.bind(this)
    this.onChange = this.onChange.bind(this)
    this.submitForm = this.submitForm.bind(this)

    this.state = {
      data: {}
    }
  }

  handleClick (e) {
    e.preventDefault()
    this.submitForm()
  }

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

  submitForm () {
    const { data } = this.state
    SuperAgent
      .post('https://something.com')
      .set('Content-Type', 'application/json')
      .send({
        data: {
          'name': 'name',
          'formName': 'form',
          'emailName': 'email',
          data
        }})
      .end((err, res) => {
        if (err || !res || !res.body) return console.log(err)
        window.location='/contact-form-successful.html'
      })
  }

  render () {
    return (
      <section className='contact-form' id={this.props.id}>
          <form id='contact-form' method='post' action='#' onSubmit={this.handleClick}>
            <input
              name="username"
              type="text"
              value=''
              onChange={this.onChange}
            />
            <input
              name="email"
              type="email"
              value=''
              onChange={this.onChange}
            />
            <input
              name="birthdate"
              type="text"
              value=''
              onChange={this.onChange}
            />
            <button>Send data!</button>
          </form>
      </section>
    )
  }
}

export default ContactForm

ContactForm.propTypes = {
  id: string
}

ContactForm.defaultProps = {
  id: 'contact-form'
}
like image 820
user2953989 Avatar asked Apr 06 '26 14:04

user2953989


2 Answers

You're using setState wrong

this.setState(...this.state.data, {[e.target.name]: e.target.value })

Should be

 const { target : { value, name } } = e
 this.setState(prevState => ({
     data: {
        ...prevState.data,
        [name]: value
     }
 }))

Also the input's value should reflect the state (controlled input)

<input
   name="username"
   type="text"
   value={this.state.username}
   onChange={this.onChange}
 />
like image 146
Dupocas Avatar answered Apr 09 '26 02:04

Dupocas


Your onChange method should rather do this :

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

like image 32
giuseppedeponte Avatar answered Apr 09 '26 02:04

giuseppedeponte



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!