React 组件【3】

136 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第12天,点击查看活动详情

前言

前面已经基本介绍完 React 组件的相关知识,现在可以介绍一下 React 组件中的表单处理。

1. 表单处理

1.1 受控组件

  • HTML 中的表单元素是可输入的,也就是有自己的可变状态
  • 而,React 中可变状态通常保存在 state 中,并且只能通过 setState() 方法来修改
  • React 将 state 与表单元素值 value 绑定到一起,由 state 的值来控制表单元素的值
  • 受控组件:其值受到 React 控制的表单元素

具体步骤

  1. 在 state 中添加一个状态,作为表单元素的 value 值(控制表单元素的来源)
  2. 给表单元素绑定 change 事件,将表单元素的值设置为 state 的值(控制表单元素值的变化)
class App extends React.Component{
  state = {
    count: ''
  }

  handleChange = e =>{
    this.setState({
      count: e.target.value
    })
  }

  render(){
    return (
      <div>
        <input type="text" value={this.state.count} onChange={this.handleChange}/>
      </div>
    )
  }
}

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

示例

  1. 文本框、富文本框、下拉框,操作 value 属性
  2. 复选框,操作 checked 属性
class App extends React.Component{
  state = {
    txt: '',
    content: '',
    city: 'bj',
    isChecked: false
  }

  // 处理输入框的变化
  handleTxt = e =>{
    this.setState({
      txt: e.target.value
    })
  }

  // 处理富文本框的变化
  handleContent = e =>{
    this.setState({
      content: e.target.value
    })
  }

  // 处理下拉框的变化
  handleCity = e =>{
    this.setState({
      city: e.target.value
    })
  }

  // 处理复选框的变化
  handleChecked = e =>{
    this.setState({
      isChecked: e.target.checked
    })
  }

  render(){
    return (
      <div>
        {/* 文本框 */}
        <input type="text" value={this.state.txt} onChange={this.handleTxt}/>
        <br />

        {/* 富文本框 */}
        <textarea  value={this.state.content} onChange={this.handleContent}></textarea>
        <br />

        {/* 下拉框 */}
        <select value={this.state.city} onChange={this.handleCity}>
          <option value="bj">北京</option>
          <option value="sh">上海</option>
          <option value="gz">广州</option>
        </select>
        <br />

        {/* 复选框 */}
        <input type="checkbox" checked={this.state.isChecked} onChange={this.handleChecked}/>

      </div>
    )
  }
}

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

多表单元素优化:

  • 问题:每个表单元素都有一个单独的事件处理程序处理太繁琐了
  • 优化:使用一个事件处理程序同时处理多个表单元素

优化步骤:

  1. 给表单元素添加 name 属性,名称与 state 相同
  2. 根据表单元素类型获取对应值
  3. 在 change 事件处理程序中通过 [name] 来修改对应的 state
class App extends React.Component{
  state = {
    txt: '',
    content: '',
    city: 'bj',
    isChecked: false
  }

  handleChange = e =>{
    // 获取当前 DOM 对象
    const target = e.target

    // 根据类型获取值
    const value = target.type === 'checkbox' ? target.checked : target.value

    // 获取 name
    const name = target.name

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

  render(){
    return (
      <div>
        {/* 文本框 */}
        <input name='txt' type="text" value={this.state.txt} onChange={this.handleChange}/>
        <br />

        {/* 富文本框 */}
        <textarea name='content' value={this.state.content} onChange={this.handleChange}></textarea>
        <br />

        {/* 下拉框 */}
        <select name='city' value={this.state.city} onChange={this.handleChange}>
          <option value="bj">北京</option>
          <option value="sh">上海</option>
          <option value="gz">广州</option>
        </select>
        <br />

        {/* 复选框 */}
        <input name='isChecked' type="checkbox" checked={this.state.isChecked} onChange={this.handleChange}/>

      </div>
    )
  }
}

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

1.2 非受控组件

  • 说明:借助于 ref,使用原生 DOM 方式来获取表单元素值
  • ref 的作用:获取 DOM 或组件 

使用步骤:

  1. 调用 React.createRef() 方法创建一个 ref 对象
  2. 将创建好的 ref 对象添加到文本框中
  3. 通过 ref 对象获取到文本框的值
class App extends React.Component{
  constructor(){
    super()

    // 创建ref
    this.txtRef = React.createRef()
  }

  // 获取文本框的值
  handleClick = () =>{
    console.log('文本框的值为:'+ this.txtRef.current.value)
  }

  render(){
    return (
      <div>
        <input type="text" ref={this.txtRef} />

        <button onClick={this.handleClick}>获取文本框的值</button>
      </div>
    )
  }
}

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