【问题标题】:React: update state with form data onChange using the spread operatorReact:使用扩展运算符使用表单数据 onChange 更新状态
【发布时间】:2019-09-26 14:16:46
【问题描述】:

我正在尝试使用扩展运算符更新我的状态,以便可以在 http 请求中传递表单数据,但从我在 console.logs 中看到的内容来看,它似乎根本没有更新。

我还收到错误“TypeError:传播不可迭代实例的无效尝试”。不过,我需要将传入的数据作为对象。

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'
}

【问题讨论】:

标签: javascript reactjs


【解决方案1】:

你用错了setState

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

应该是

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

输入的value 也应该反映state(受控输入)

<input
   name="username"
   type="text"
   value={this.state.username}
   onChange={this.onChange}
 />

【讨论】:

  • 它是一种单向的数据绑定,状态的值反映在各自的input
  • 其实这里的正确术语是可控的。但你是对的,根本不是两种方式
【解决方案2】:

您的 onChange 方法应该这样做:

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

【讨论】:

  • 您正在更新整个状态,而不仅仅是 state.data 属性。
【解决方案3】:

扩展运算符的正确语法用法如下:

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

但是,您不需要使用setState 进行传播,您只需更新您需要的内容。

因此您只能设置如下状态:

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

如果您想依赖先前的状态值,那么您必须使用函数式setState

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

除此之外,您还缺少要从 React 组件状态检索的输入值,而是将其硬编码为 '' 空字符串,因此值永远不会反映在输入中,而您的状态会随着最后一个键输入而不断更新。

        <input
          name="username"
          type="text"
          value={this.state.username}
          onChange={this.onChange}
        />
        <input
          name="email"
          type="email"
          value={this.state.email}
          onChange={this.onChange}
        />
        <input
          name="birthdate"
          type="text"
          value={this.state.birthdate}
          onChange={this.onChange}
        />

【讨论】:

  • 谢谢,用这些解决方案不会让我输入输入框吗?
  • 您还必须将每个输入值设置为其各自的状态属性
  • 这是另一个问题以及第一个语法问题,使用正确的输入绑定更新了答案。
猜你喜欢
  • 2018-06-25
  • 1970-01-01
  • 2018-12-09
  • 2019-07-27
  • 2021-03-25
  • 1970-01-01
  • 2021-12-01
  • 2018-05-17
  • 2020-02-11
相关资源
最近更新 更多