react学习10-React 表单受控和非受控组件的基本使用

React 表单受控和非受控组件的基本使用

在 React 里,HTML 表单元素的工作方式和其他的 DOM 元素有些不同,这是因为表单元素通常会保持一些内部的 state。

受控组件

渲染表单的 React 组件还控制着用户输入过程中表单发生的操作。

被 React 以这种方式控制取值的表单输入元素就叫做“受控组件”。

对于受控组件来说,输入的值始终由 React 的 state 驱动。

不同的表单项数据处理(受控组件)

  • input、select和textarea处理方式一样
  • 将state值绑定到表单输入域value属性上
  • 监听表单输入域onChange事件,事件函数中动态更新状态值

input

<div>
    {/*label标签的for属性需要修改为htmlFor,因为for是关键字*/}
    <label htmlFor='uname'>用户名:</label>
    <input value={this.state.uname} onChange={this.handleUname} type="text" id="uname"/>
</div>
handleUname = (e) => {
    // 监听表单输入域的值的变化
    this.setState({
      uname: e.target.value
    })
}

radio

<div>
    <label>性别:</label>
    <label htmlFor="male"></label>
    <input checked={gender === '1'? true: false} onChange={this.handleGender} value='1' type="radio" name='gender' id="male"/>
    <label htmlFor="female"></label>
    <input checked={gender === '2'? true: false} onChange={this.handleGender} value='2' type="radio" name='gender' id="female"/>
</div>
handleGender = (e) => {
    // 监听radio值的变化
    this.setState({
        gender: e.target.value
    })
}

select

<div>
    <label htmlFor="job">工作:</label>
    <select id="job" value={job} onChange={this.handleItem}>
        <option value="1">程序猿</option>
        <option value="2">产品狗</option>
        <option value="3">测试</option>
    </select>
</div>
handleItem = (e) => {
    // 监听select值的变化
    this.setState({
      [e.target.id]: e.target.value
    })
  }

checkbox

<div>
    <label>兴趣:</label>
    <label htmlFor="coding">写代码</label>
    <input checked={favour.includes('coding')} onChange={this.handleFavour} value='coding' name='favour' type="checkbox" id="coding"/>
    <label htmlFor="singing">唱歌</label>
    <input checked={favour.includes('singing')} onChange={this.handleFavour} value='singing' name='favour' type="checkbox" id="singing"/>
    <label htmlFor="dancing">跳舞</label>
    <input checked={favour.includes('dancing')} onChange={this.handleFavour} value='dancing' name='favour' type="checkbox" id="dancing"/>
</div>
handleFavour = (e) => {
    // 监听兴趣的选择
    // console.log(e.target.value)
    // 当前点击的选框的值
    let v = e.target.value
    // 如果favour数组中包含v这个值,需要删除,如果不包含,就添加进去
    let newFavour = [...this.state.favour]
    let flag = newFavour.some(item => item === v)
    if (flag) {
        // 已经存在,那就删除该值
        let index = newFavour.findIndex(item => item === v)
        newFavour.splice(index, 1)
    } else {
        // 尚不存在,那就添加该值
        newFavour.push(v)
    }
    this.setState({
        favour: newFavour
    })
}

textarea

<div>
    <label htmlFor="desc">个人介绍:</label>
    <textarea value={desc} onChange={this.handleItem} id="desc" cols="30" rows="10"></textarea>
</div>
handleItem = (e) => {
    this.setState({
        [e.target.id]: e.target.value
    })
}

非受控组件

非受控组件用法:

  1. 创建ref实例对象
  2. 把ref对象关联到标签上
  3. 通过ref对象的current属性可以得到原生DOM对象

非受控组件的应用场景:

  1. 获取输入域的焦点
  2. 文件上传获取文件信息
  • 通过ref实例对象current属性可以得到原生DOM对象,(类似于vue中ref,本质上就是直接操作DOM)。

  • 可以使用defaultValue指定表单的默认值

    // 构造函数
    this.textInput = React.createRef();
    // 标签中
    <input type="text" ref={this.textInput} />
    // 使用
    this.textInput.current.focus();
    
  • 文件上传应用

    this.fileRef = React.createRef();
    let fileInfo = this.fileRef.current.files[0];
    <input type="file" id="file" ref={this.fileRef}/>
    

示例代码

import React from 'react'

class FormTest extends React.Component {

  inputRef = React.createRef()

  fileRef = React.createRef()

  handleClick = () => {
    // let v = this.inputRef.current.value
    // console.log('获取表单数据:' + v)

    // 获取选中的文件信息
    let file = this.fileRef.current.files[0]
    // 选中文件之后,下一步就是把file对象提交到后台接口即可
    console.log(file)
  }

  componentDidMount () {
    // 获取输入域的焦点
    this.inputRef.current.focus()
  }

  render () {
    return (
      <div>
        <h1>非受控组件用法</h1>
        <hr/>
        <label htmlFor="uname">用户名</label>
        <input ref={this.inputRef} type="text" id="uname"/>
        <hr/>
        <div>
          <input ref={this.fileRef} type="file" />
        </div>
        <button onClick={this.handleClick}>点击</button>
      </div>
    )
  }
}

export default FormTest
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值