09-组件化高级-form表单受控元素提交

47 阅读1分钟

本章以demo为例介绍一个全受控表单元素的 change数据维护 以及 表单提交

demo

交互

image.png

代码

import React, { PureComponent } from 'react'

export class App extends PureComponent {
  constructor() {
    super()
    this.state = {
      username: 'momomo',
      password: '',
      agree: false,
      hobbies: [
        {
          value: 'sing',
          text: '唱',
          isChecked: false
        },
        {
          value: 'play games',
          text: '玩游戏',
          isChecked: false
        },
        {
          value: 'swim',
          text: '游泳',
          isChecked: false
        }
      ],
      fruit: 'purple',
      fruits: []
    }
  }
  handleSubmit (e) {
    // 原始type=submit类型的提交,会导致提交后页面刷新
    // 现在使用点击事件,获取到表单元素数据,进行操作数据,再通过ajax发送网络请求

    // 1、阻止默认行为
    e.preventDefault()
    console.log('获取所有输入内容', this.state)
  }
  handleChange (e) {
    this.setState({
      username: e.target.value
    })
  }
  handleChangePwd (e) {
    this.setState({
      password: e.target.value
    })
  }
  handleInputChange (e) {
    console.log(e.target.name, e.target.checked)
    const key = e.target.name
    this.setState({
      [key]: key === 'agree' ? e.target.checked : e.target.value
    })
  }
  changeBox (e) {
    console.log(e.target.name, e.target.checked)
    const hobbies = [...this.state.hobbies]
    hobbies.find(item => item.value === e.target.name).isChecked = e.target.checked
    this.setState({
      hobbies
    })
  }
  handleChangeSelect (e) {
    console.log(e.target.name, e.target.selectedOptions)
    const options = Array.from(e.target.selectedOptions)
    console.log(options)
    const values = options.map(item => item.value)
    // Array.form(可迭代对象,mapFunc)
    const values1 = Array.from(e.target.selectedOptions, item => item.value)
    // this.setState({
    //   [e.target.name]: e.target.value
    // })
    this.setState({
      fruits: values1
    })
  }
  render () {
    const { username, password, agree, hobbies, fruit, fruits } = this.state
    return (
      <div>
        <form action="/abc" onSubmit={(e) => this.handleSubmit(e)}>
          <label htmlFor='username'>
            用户:<input name="username" id="username" value={username} onChange={(e) => this.handleInputChange(e)} />
          </label>
          <label htmlFor='username'>
            密码:<input name="password" id="password" value={password} onChange={(e) => this.handleInputChange(e)} />
          </label>
          <div>
            <label htmlFor='agree'>
              <input name="agree" id="agree" type="checkbox" checked={agree} onChange={(e) => this.handleInputChange(e)} />同意协议
            </label>
          </div>
          <div>
            您的爱好:
            {
              hobbies.map(item => {
                return (
                  <label htmlFor={item.value} key={item.value}>
                    <input name={item.value} id={item.value} type="checkbox" checked={item.isChecked} onChange={(e) => this.changeBox(e)} />{item.text}
                  </label>
                )
              })
            }
          </div>
          <div>水果
            <select name="fruit" value={fruits} multiple onChange={(e) => this.handleChangeSelect(e)}>
              <option value="apple">apple</option>
              <option value="bnana">bnana</option>
              <option value="purple">purple</option>
            </select>
          </div>
          <button type="submit">提交</button>
        </form>
      </div>
    )
  }
}

export default App

结论:

  • form元素中自定义onSubmit 事件进行逻辑处理:onSubmit={(e) => this.handleSubmit(e)}
  • 每个表单项变为受控组件2要素:value绑定state的值,增加onChange事件,且都叫onChange
  • onChange={(e)=> handler(e)}e必须传递,且在handler中通过e.target.name获取state的key,通过e.target.value获取input/textarea/单选select的值。通过Array.from(e.target.selectedOptions, item=>item.value)获取多选select值。通过e.target. checked获取checkbox的值
  • 最终的handleSubmit事件通过this.state获取受控元素的值

image.png