react 中:类组件如何获取表单元素的值?

489 阅读3分钟

一、受控组件

1.受控组件的含义及使用步骤

受控组件含义: value 值受到了 react 控制的表单元素

使用步骤如下:

  • state 中定义状态
  • 对表单元素做两件事
    • 设置 value 为上面定义的状态
    • 绑定 onChange 事件,并在回调中通过 setState 来修改状态值

2.受控组件使用示例

第一步:创建项目,进行初始化

  • npx create-react-app react-input
  • cd react-input
  • yarn start 或 npm start 或 npm run start
  • 新建 src/components/CtrlClass.js

image.png

第二步:index.js 入口

import React from 'react'
import ReactDOM from 'react-dom'

import App from './App'

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

第三步:App.js 出口

import React from 'react'
// 导入 受控组件 CtrlClass 组件 
import CtrlClass from './components/CtrlClass'

class App extends React.Component {
  render() {
    return <div>
      <CtrlClass></CtrlClass>
    </div>
  }
}
export default App

第四步:CtrlClass.js 书写受控组件的内容

import React from 'react'
// ◆类组件
class CtrlClass extends React.Component {
    // 1.定义表单的变量值
    state = {
        txtVal: '123',
        areaVal: '456',
        selectVal: 'b',
        chkFlag: true
    }
    // 2.文本框输入事件
    changeTxtVal = (e) => {
        console.log(e, 'changeVal')
        this.setState({
            txtVal: e.target.value
        })
    }
    // 3.文本域输入事件
    changeAreaVal = (e) => {
        console.log(e, 'changeTextVal')
        this.setState({
            areaVal: e.target.value
        })
    }
    // 4.下拉框选中事件
    changeSelectVal = (e) => {
        console.log(e, 'changeSelectVal')
        this.setState({
            selectVal: e.target.value
        })
    }
    // 5.复选框选中事件
    changeChkFlag = (e) => {
        console.log(e, 'changeChkFlag')
        this.setState({
            chkFlag: e.target.checked
        })
    }

    // 6.渲染页面
    render() {
        return <div style={{width:'200px',backgroundColor:'skyblue'}}>
            <p>表单值实时变化:{this.state.txtVal}</p>
            <input type="text" value={this.state.txtVal} onChange={this.changeTxtVal} />
            <hr />
            <p>文本域值实时变化:{this.state.areaVal}</p>
            <textarea value={this.state.areaVal} onChange={this.changeAreaVal}></textarea>
            <hr />
            <p>下拉菜单值实时变化:{this.state.selectVal}</p>
            <select value={this.state.selectVal} onChange={this.changeSelectVal}>
                <option value="a">1</option>
                <option value="b">2</option>
                <option value="c">3</option>
            </select>
            <hr />
            <p>复选框值实时变化:{this.state.chkFlag?'true':'false'}</p>
            <input type="checkbox" checked={this.state.chkFlag} onChange={this.changeChkFlag} />敲代码
        </div>
    }
}
export default CtrlClass

第五步:页面展示

image.png

第六步:代码优化

相信你已经发现了,上述除了 复选框 是通过 e.target.checked 获取,其他的都是 e.target.value。至此,咱们可以给它来一个封装复用,使所有表单共用一个 change 事件。何以实现?给每个表单增加一个 name 属性,然后通过对 name 的判断,赋对应的值。代码优化如下:

import React from 'react'
// ◆ 类组件
class CtrlClass extends React.Component {
    state = {
        txtval: '123',
        areaVal: '456',
        selectVal: 'b',
        chkFlag: true
    }
    // ◆表单 change 事件
    changeValHandler = (e) => {
        console.log(e, 'changeHandler')
        console.log(e.target.name, 'changeHandler')
        // 解构
        const { name } = e.target
        this.setState({
            // 对象的写法
            [name]: name === 'chkFlag' ? e.target.checked : e.target.value
        })
    }

    render() {
        return <div style={{ width: '200px',backgroundColor:'skyblue'}}>
            <p>表单值实时变化:{this.state.txtval}</p>
            <input name='val' type="text" value={this.state.txtval} onChange={this.changeValHandler} />
            <hr />
            <p>文本域值实时变化:{this.state.areaVal}</p>
            <textarea name='textVal' value={this.state.areaVal} onChange={this.changeValHandler}></textarea>
            <hr />
            <p>下拉菜单值实时变化:{this.state.selectVal}</p>
            <select name='selectVal' value={this.state.selectVal} onChange={this.changeValHandler}>
                <option value="a">1</option>
                <option value="b">2</option>
                <option value="c">3</option>
            </select>
            <hr />
            <p>复选框值实时变化:{this.state.chkFlag ? 'true' : 'false'}</p>
            <input name='chkFlag' type="checkbox" checked={this.state.chkFlag} onChange={this.changeValHandler} />敲代码
        </div>
    }
}
export default CtrlClass

二、非受控组件

1.非受控组件的含义及使用步骤

非受控组件含义: 借助于 ref,使用原生 DOM 的方式来获取表单元素的值

使用步骤如下:

  • 调用 React.createRef 方法创建引用,假设名为 txtRef
    • const txtRef = React.createRef()
  • txtRef 设置给表单元素的 ref 属性
    • <input ref={txtRef}/>
  • 通过 txtRef.current.value 来获取值。
    • console.log(this.txtRef.current.value)

2.非受控组件使用示例

第一步:在上面项目基础下,新建 src/components/UnCtrlClass.js

image.png

第二步:App.js 出口文件 导入非受控组件

import React from 'react'
// 导入 受控组件 CtrlClass  
import CtrlClass from './components/CtrlClass'
// 导入非受控组件 UnCtrlClass
import UnCtrlClass from './components/UnCtrlClass'

class App extends React.Component {
  render() {
    return <div>
      <CtrlClass></CtrlClass>
      <UnCtrlClass></UnCtrlClass>
    </div>
  }
}
export default App

第三步:UnCtrlClass.js 书写非受控组件的内容

import React from 'react'
class UnCtrlClass extends React.Component {
    // ◆1.定义表单的变量值
    state = {
        txtval: '123',
        areaVal: '456',
        selectVal: 'b',
        chkFlag: true
    }
    // 2.创建 ref
    txtRef = React.createRef()
    areaRef = React.createRef()
    selRef = React.createRef()
    chkRef = React.createRef()

    // ◆3.文本框输入事件
    changeTxtVal = () => {
        console.log(this,'changeVal')
        this.setState({
            txtval: this.txtRef.current.value
        })
    }
    // ◆4.文本域输入事件
    changeAreaVal = () => {
        console.log(this, 'changeTextVal')
        this.setState({
            areaVal: this.areaRef.current.value
        })
    }
    // ◆5.下拉框选中事件
    changeSelectVal = () => {
        console.log(this, 'changeSelectVal')
        this.setState({
            selectVal: this.selRef.current.value
        })
    }
    // ◆6.复选框选中事件
    changeChkFlag = () => {
        console.log(this, 'changeChkFlag')
        this.setState({
            chkFlag: this.chkRef.current.checked
        })
    }
    // ◆7.页面渲染(调用)
    render() {
        return <div style={{ width: '200px' ,backgroundColor:'pink'}}>
            <p>文本框值实时变化:{this.state.txtval}</p>
            <input type="text" ref={this.txtRef}  onChange={this.changeTxtVal} />
            <p>文本域值实时变化:{this.state.areaVal}</p>
            <textarea ref={this.areaRef}  onChange={this.changeAreaVal}></textarea>
            <hr />
            <p>下拉菜单值实时变化:{this.state.selectVal}</p>
            <select ref={this.selRef} onChange={this.changeSelectVal}>
                <option value="a">1</option>
                <option value="b">2</option>
                <option value="c">3</option>
            </select>
            <hr />
            <p>复选框值实时变化:{this.state.chkFlag ? 'true' : 'false'}</p>
            <input type="checkbox" ref={this.chkRef}  onChange={this.changeChkFlag} />敲代码
        </div>
    }
}
export default UnCtrlClass

第四步:页面显示

image.png