React表单处理

在React中关于表单分为两部分内容,受控组件和非受控组件。

4.7.1 受控组件

我们知道,在HTML中的表单元素是可以输入数据的(也可以进行删除),也就是有自己的可变状态。例如文本框,可以在文本框中输入内容,也可以进行删除,而输入的内容我们可以称之为可变的状态。而这个状态是有HTML表单元素自己维护的。

但是在React中,我们知道可变的状态通常保存在state中,并且只能通过setState方法来进行修改。

这时与HTML中的表单元素在状态的维护上产生了冲突。为了解决这个冲突,React将state与表单元素的值value绑定到一起,由state的值来控制表单元素的值。

所以我们将其值受到React控制的表单元素称之为受控组件。

import React,{Component}from 'react'
class App extends Component{
    state={
        num:10
    }
    handleChange=e=>{
        this.setState({
            num:e.target.value
        })
    }
    render(){
        return (
            
{this.state.num}
) } } export default App

在这里,将React中state状态与文本框中的value属性进行了绑定,然后给文本框添加了一个onChange,当在文本框中输入值的时候,会调用handleChange方法,在这个方法中通过e.target.value获取文本框中输入的值,然后重新给了state,这时在div中展示的state中的num也发生了相应的变化。

下面再看几个受控组件的案例:

富文本框案例

富文本框的实现和文本框的实现基本上是一样的,代码如下所示:

import React,{Component}from 'react'
class App extends Component{
    state={
        content:'Hello'
    }
    handleChange=e=>{
        this.setState({
            content:e.target.value
        })
    }
    render(){
        return (
            
{this.state.content}
) } } export default App

下拉框应用

import React,{Component}from 'react'
class App extends Component{
    state={
        city:'shanghai'
    }
    handleChange=e=>{
        this.setState({
            city:e.target.value
        })
    }
    render(){
        return (
            
{this.state.city}
) } } export default App

在上面的代码中,定义的state中的city取值为'shanghai',并与select标签的value属性进行了绑定了,这时会默认显示’上海‘这一项。当选择下拉框中的不同的选项时,会执行onChange对应的handleChange方法,在该方法中获取用户选择的项的value值,然后重新赋值state.

复选框应用
 

import React,{Component}from 'react'
class App extends Component{
    state={
        isChecked:true
    }
    handleChange=e=>{
        this.setState({
            isChecked:e.target.checked
        })
    }
    render(){
        return (
            
复选框
) } } export default App

注意,这里获取的是复选框的checked.

更新完复选框的状态后,想立即查看对应的状态值。
 

import React, { Component } from "react";
class ControlComponent extends Component {
  state = {
    isChecked: true,
  };
  handleChange = (e) => {
    this.setState({ isChecked: e.target.checked }, () => {
      console.log(this.state.isChecked);
    });
  };
  render() {
    return (
      
复选框
); } } export default ControlComponent;

上面的代码,给setState方法添加了第二个参数,第二个参数是一个回调函数,当状态更新成功后,会立即调用

受控组件更新state流程

通过前面打的案例,这里可以总结出React受控组件更新state的流程

(1)可以通过在初始state中设置表单的默认值。

(2)给表单添加onChange,并且当表单中的值发生了变化时,会调用onChange所指定的函数。

(3) 在所对应的处理函数中通过合成事件对象获取到表单改变后的状态,并且更新对应的state.

(4)setState触发页面的重新渲染,完成表单中值的更新。

其实通过整个流程的分析,可以发现最开始表单中的数据来源于state,也就是将state绑定到表单上,这其实就是单向的数据绑定。然后,我们又通过onChange事件对应的方法将在表单中输入的新的数据又更新回了state中,这样就完成了双向数据绑定。

与原生表单相比,受控组件的模式确实复杂了很多,每次表单中数据变化时,都会执行上面这几步,但是对表单中的值进行一些特殊操作的时候会变得更加容易。

例如:下面的案例要求,在文本框中输入的值不能超过60

import React,{Component}from 'react'
class App extends Component{
    state={
        num:10
    }
    handleChange=e=>{
        this.setState({
            // 获取到用户在文本框中输入的值,如果超过60,对应的state的值为10,这时文本框中显示的还是10.
            num:e.target.value>60?10:e.target.value
        })
    }
    render(){
        return (
            
{this.state.num}
) } } export default App

表单处理优化

现在,我们思考一个问题,如果一个页面中需要的表单元素比较多,应该怎样进行处理呢?

如果还是按照前面的方式进行处理,那么需要写很多的方式。这样就比较麻烦了。所以,这里可以将多个表单元素的处理封装到一个方法中完成,但是问题是,在这个方法中需要处理不同的表单元素,那么应该怎样进行区分呢?

这时要考虑的问题,下面先看一下具体的实现步骤:

- 给表单元素添加name属性(用来区分是哪一个表单),名称与state相同(用来更新数据的)
- 根据表单内容来获取对应值
- 在change事件处理程序中通过 [name] 来修改对应的state.

通过具体的实现步骤:

可以发现,要想在方法中能够区分开所处理的表单元素,需要通过name属性来完成。

具体代码实现如下:
 

import React,{Component}from 'react'
class App extends Component{
    state={
        num:10,
        content:'Hello',
        city:'shanghai',
        isChecked:true
    }
    handleChange=e=>{
        // 获取当前的元素.
        const target = e.target;
        //判断元素的类型
      const value=target.type==='checkbox'?target.checked:target.value;
      console.log(value);
      //获取name
      const name=target.name;
        this.setState({
            [name]:value
        })
    }
    render(){
        return (
            
{this.state.num} {this.state.content} {this.state.city}
复选框
) } } export default App

非受控组件

非受控组件,不在受状态state的控制。它需要借助于ref, 使用元素DOM方式获取表单元素值。

ref的作用就是用来获取DOM的,所以说这种方式是直接操作DOM的方式。

具体的实现步骤如下:

- 调用 React.createRef() 方法创建ref对象
- 将创建好的 ref 对象添加到文本框中
- 通过ref对象获取到文本框的值

代码演示如下所示:(单击按钮,获取文本框中的值)
 

import React,{Component}from 'react'
class App extends Component{
    constructor(){
        super()
        //创建ref,将创建好的ref赋值给当前的this
      this.txtRef= React.createRef()
    }
    getValue=()=>{
        //获取文本框中的值(注意这里需要添加current)
        console.log(this.txtRef.current.value)
    }
    render(){
        return (
            
{/* 将创建好的ref与当前文本框关联起来 */}
) } } export default App

学IT,上博学谷

你可能感兴趣的:(React,前端,react.js)