React之数据绑定以及表单处理

一、表单元素

        像<input>、<textarea>、<option>这样的表单元素不同于其他元素,因为他们可以通过用户交互发生变化。这些元素提供的界面使响应用户交互的表单数据处理更加容易

        交互属性,用户对一下元素交互时通过onChange回调函数来监听组件变化。表单元素支持几个受用户交互影响的属性:

        value用于<input>、<textarea>

        checked用于<checkbox>、<radio>

        selected用于<option>

二、受限组件和不受限组件

1.受限组件与双向数据绑定

受限组件:设置了value的<input>是一个受限组件,对于受限的<input>,渲染出来HTML元素始终保持value属性的值,此时用户在渲染出来的组件里输入任何值都不起作用

 写一个完整的表单元素的实例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>受限组件和双向绑定</title>
    <script src="../js/react.development.js "></script>
    <script src="../js/react-dom.development.js"></script>
    <!-- 用于解析babel -->
    <script src="../js/babel.min.js"></script>
</head>

<body>
    <div id="hello">
    </div>
    <div id="hello2">
    </div>
    <script type="text/babel">
        //受限组件,他的
        class Hello extends React.Component{
            
            render(){
                return <div>
                    <input type="text" value='123'/>
                    <hr/>
                </div>
               
            }
        }
        ReactDOM.render(<Hello />,document.getElementById('hello'))
        //双向数据绑定
        class Hello2 extends React.Component{
            state = {
                value:'12345'
            }
            //
            valueChange = (e)=>{
                this.setState({value:e.target.value})
            }
            render(){
                return <div>
                    <input type="text" value={this.state.value} onChange={this.valueChange}/>
                    <p>{this.state.value}</p>
                </div>
            }
        }
        ReactDOM.render(<Hello2 />,document.getElementById('hello2'))
    </script>
    <!-- radio、checkbox、textarea、select -->
    <hr/>
    <div id="root1"></div>
    <script type="text/babel">
        //表单元素的双向绑定
        class Rtx extends React.Component{
            state = {
                //单选按钮
                radioValue:'',
                //check选中的
                checkArr:[],
                //文本域的value
                textareaValue:'',
                selectArr: ['北京','上海','湖北','广东'],
                //select选中的地址
                address:''
            }
            //
            radioChange = (e)=>{
                this.setState({radioValue:e.target.value})
            }
            checkboxChange =(e)=>{
                //由于组件继承的是purecomponent,因此要将数组复制一次
                let _checkArr = [...this.state.checkArr]
                if (e.target.checked) {
                    //将所有选中的复选框的value值,push到一个数组(checkArr)中
                    _checkArr.push(e.target.value)
                } else {
                    //若取消选中,则将其从checkArr中减掉
                    _checkArr.splice(this.state.checkArr.indexOf(e.target.value), 1)
                }
                //利用setState更新checkArr
                this.setState({
                    checkArr:_checkArr
                })
            }
            textareaChange=(e)=>{
                this.setState({textareaValue:e.target.value})
            }
            selectChange=(e)=>{
                this.setState({address:e.target.value})
            }
            submit =()=>{
                console.log(this.state);
            }
            render(){
                let checkInfo=["c1",'c2']
                let {radioValue,checkArr,textareaValue,selectArr,address } =this.state
                let {checkboxChange} =this
                return <div>
                   <div>
                    性别:
                     男<input type="radio" value='man' checked={radioValue=='man'?true:false}  onChange={this.radioChange}/>
                     女<input type="radio" value='woman' checked={radioValue=='woman'?true:false} onChange={this.radioChange}/>
                    </div>
                    <div>
                        {
                            checkInfo.map(function(item,index){
                                return <span>
                                    {item}
                                    <input type="checkbox" name='box' value={item} key={index} 
                                    onChange={checkboxChange} 
                                    checked={checkArr.indexOf(item)!==-1}></input>
                                    </span> 
                            })
                        }
                    </div>
                    <div>
                        <textarea name="" id="" value={textareaValue} cols="30" rows="10" onChange={this.textareaChange}></textarea>
                    </div>
                    <div>
                        地址:
                        <select value={address} name="address" onChange={this.selectChange}>
                        {
                            selectArr.map(function(item,index){
                            return <option key={index}>{item}</option>
                            })
                        }
                        </select>   
                    </div>
                    <button disabled={!radioValue || !address || !checkArr ||  !textareaValue } onClick={()=>this.submit()}>提交</button>
                </div>
            }
        }
        ReactDOM.render(<Rtx />,document.getElementById('root1'))
    </script>
    <!-- radio、
</body>

</html>

2.不受限组件

不受限组件: 没有设置value(或者设为null)的input组件是一个不受限组件。杜宇不受限的input组件,渲染出来的元素直接反映用户输入

 使用defaultValue属性不使用value可以实现不受限组件的双向数据

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>非受限组件</title>
    <script src="../js/react.development.js "></script>
    <script src="../js/react-dom.development.js"></script>
    <!-- 用于解析babel -->
    <script src="../js/babel.min.js"></script>
</head>

<body>
    <div id="root1"></div>
    <script type="text/babel">
        //非受限组件
        class Rtx extends React.Component {
            state = {
                value: '123'
            }
            valueChange = (e) => {
                this.setState({ value: e.target.value })
                console.log(this.state.value);
            }
            render() {

                return <div>
                    <div>
                        <input type="text" />
                        <input type="text" defaultValue={this.state.value} onChange={this.valueChange} />
                        <p>{this.state.value}</p>
                    </div>
                    <div>
                        性别:
                        男<input type="radio" name='sex' value='man' />
                        女<input type="radio" name='sex' value='woman' />
                    </div>
                </div>
            }
        }
        ReactDOM.render(<Rtx />, document.getElementById('root1'))
    </script>
    <!-- radio、checkbox、textarea、select -->
    <div id="root1"></div>
    <script type="text/babel">
        //表单元素的双向绑定
        class Rtx extends React.Component {
            state = {
                //单选按钮
                radioValue: '',
                //check选中的
                checkArr: [],
                //文本域的value
                textareaValue: '',
                selectArr: ['北京', '上海', '湖北', '广东'],
                //select选中的地址
                address: ''
            }
            //
            radioChange = (e) => {
                this.setState({ radioValue: e.target.value })
            }
            checkboxChange = (e) => {
                //由于组件继承的是purecomponent,因此要将数组复制一次
                let _checkArr = [...this.state.checkArr]
                if (e.target.checked) {
                    //将所有选中的复选框的value值,push到一个数组(checkArr)中
                    _checkArr.push(e.target.value)
                } else {
                    //若取消选中,则将其从checkArr中减掉
                    _checkArr.splice(this.state.checkArr.indexOf(e.target.value), 1)
                }
                //利用setState更新checkArr
                this.setState({
                    checkArr: _checkArr
                })
            }
            textareaChange = (e) => {
                this.setState({ textareaValue: e.target.value })
            }
            selectChange = (e) => {
                this.setState({ address: e.target.value })
            }
            submit = () => {
                console.log(this.state);
            }
            render() {
                let checkInfo = ["c1", 'c2']
                let { radioValue, checkArr, textareaValue, selectArr, address } = this.state
                let { checkboxChange } = this
                return <div>
                    <div>
                        性别:
                        男<input type="radio" defaultValue='man'  checked={radioValue == 'man' ? true : false} onChange={this.radioChange} />
                        女<input type="radio" defaultValue='woman' checked={radioValue == 'woman' ? true : false} onChange={this.radioChange} />
                    </div>
                    <div>
                        {
                            checkInfo.map(function (item, index) {
                                return <span>
                                    {item}
                                    <input type="checkbox" name='box' defaultValue={item} key={index}
                                        onChange={checkboxChange}
                                        checked={checkArr.indexOf(item) !== -1}></input>
                                </span>
                            })
                        }
                    </div>
                    <div>
                        <textarea name="" id="" value={textareaValue} cols="30" rows="10" onChange={this.textareaChange}></textarea>
                    </div>
                    <div>
                        地址:
                        <select defaultValue={address} name="address" onChange={this.selectChange}>
                            {
                                selectArr.map(function (item, index) {
                                    return <option key={index}>{item}</option>
                                })
                            }
                        </select>
                    </div>
                    <button disabled={!radioValue || !address || !checkArr || !textareaValue} onClick={() => this.submit()}>提交</button>
                </div>
            }
        }
        ReactDOM.render(<Rtx />, document.getElementById('root1'))
    </script>
</body>

</html>

三、常用表单数据绑定

对相同逻辑的表单change事件进行封装

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>表单提交</title>
    <script src="../js/react.development.js "></script>
    <script src="../js/react-dom.development.js"></script>
    <!-- 用于解析babel -->
    <script src="../js/babel.min.js"></script>
</head>

<body>
    <div id="root1"></div>
    <script type="text/babel">
        //非受限组件
        class Rtx extends React.Component {
            state = {
                name: 'fxt',
                sex:'1',
                address:'上海',
                textareaValue:'hello world'
            }
            //我们发现下面获得改变值的方法都是一样的,所以对一样的逻辑函数进行封装
            handleChange=(e)=>{
                console.log(e.target.name);
                let key = e.target.name
                this.setState({[key]:e.target.value})
                // this.setState({[e.target.name]:e.target.value})
            }
            // getName=(e)=>{
            //     this.setState({name:e.target.value})
            // }
            // getSex=(e)=>{
            //     this.setState({sex:e.target.value})
            // }
            getAddress=(e)=>{
                this.setState({address:e.target.value})
            }
            getTextareaValue=(e)=>{
                this.setState({textareaValue:e.target.value})
            }
            submit = (e) => {
                // e.preventDefault();
                alert(JSON.stringify(this.state))
            }
            render() {
                let  selectArr=['北京', '上海', '湖北', '广东']
                let {name,sex,address,textareaValue}=this.state
                return <div>
                    <form action="">
                        <label for="">姓名:<input type="text" name='name' defaultValue={name} onChange={this.handleChange}/></label>  
                        <label for="">
                            <div>
                                性别:
                                <input type="radio" name="sex" value='1' defaultChecked={sex==1? true:false} id="" onChange={this.handleChange}/>男
                                <input type="radio" name="sex" value='2' defaultChecked={sex==2? true:false} id="" onChange={this.handleChange}/>女
                            </div>
                        </label>  
                        <label for="">
                            <div>
                                地址:
                                <select defaultValue={address} name="address" onChange={this.getAddress}>
                                    {
                                        selectArr.map( (item, index) =>{
                                            return <option key={index}>{item}</option>
                                        })
                                    }
                                </select>
                            </div>
                        </label>
                        <label for="">
                            <div>
                                备注:
                                <textarea name="" id="" defaultValue={textareaValue} cols="30" rows="10" onChange={this.getTextareaValue}></textarea>   
                            </div>
                        </label>
                        <button disabled={!name || !address || !textareaValue || !sex} onClick={()=>{this.submit()} }>提交</button>
                    </form>
                </div>
            }
        }
        ReactDOM.render(<Rtx />, document.getElementById('root1'))
    </script>
</body>

</html>

四、注册功能实现

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>注册表单验证</title>
    <script src="../js/react.development.js "></script>
    <script src="../js/react-dom.development.js"></script>
    <!-- 用于解析babel -->
    <script src="../js/babel.min.js"></script>
    <style>
        .error{
            color: red;
        }
    </style>
</head>

<body>
    <div id="root1"></div>
    <script type="text/babel">
        //非受限组件
        class Rtx extends React.Component {
            state = {
                name: '',
                nameError:"",
                passworld:'',
                passworldError:'',
                sex:'1',
                phone:'',
                phoneError:'',
                city:'北京',
                textareaValue:'hello world'
            }
            //单独写校验规则的
            nameChange=(e)=>{
                let rule= /^[\w-]{4,10}$/ 
                let value=e.target.value
                let error=''
                if(!value){
                    error='请输入昵称'
                }else if(!rule.test(value)){
                    error='请输入4-10位的昵称'
                }else{
                    error=''
                }
                this.setState({
                    name:value,
                    nameError:error
                })
            }
            //进行校验的表单元素统一封装
            handleTest=(e)=>{
                let ruleArr={
                    passworld:{
                        rule:new RegExp(/^\S*(?=\S{6,12})(?=\S*\d)(?=\S*[A-Z])(?=\S*[a-z])(?=\S*[!@#$%^&*? ])\S*$/),
                        text:'密码',
                        error:'6-12位,至少包括一个大小写字母、数字、特殊字符'
                    },
                    phone:{
                        rule:new RegExp(/^(?:(?:\+|00)86)?1[3-9]\d{9}$/),
                        text:'手机号',
                        error:'请输入正确的手机号'
                    }
                }
                let value=e.target.value
                let key = e.target.name
                let ruleInfo={}
                let error=''
                Object.keys(ruleArr).map((el)=>{
                    if(el==key){
                        ruleInfo=ruleArr[key]
                    }
                })
                if(!value){
                    error='请输入'+ruleInfo.text
                }else if(!ruleInfo.rule.test(value)){
                    error=ruleInfo.error
                }else{
                    error=''
                }
                this.setState({
                    [key]:value,
                    [key+'Error']:error
                })
            }
            //不进行校验的表单通过自定义属性实现获得要设置的值的key键
            handleChange=(e)=>{
                console.log(e.target.name);
                let key = e.target.name
                this.setState({[key]:e.target.value})
                // this.setState({[e.target.name]:e.target.value})
            }
            //提交想提交值
            submit = (e) => {
                e.preventDefault()//阻止默事件
                let {name,passworld,sex,phone,city,textareaValue} =this.state
                let data={
                    name,passworld,sex,phone,city,textareaValue
                }
                alert(JSON.stringify(data))
            }
            render() {
                let  selectArr=[{id:1,text:'北京'},{id:2,text: '上海'}, {id:3,text:'湖北'}]
                let {name,nameError,passworld,passworldError,sex,phone,phoneError,city,textareaValue}=this.state
                return <div>
                    <form action="">
                        <label for="">
                            昵称:<input type="text" name='name' defaultValue={name} onChange={this.nameChange}/>
                            <span className='error'> * {nameError}</span>
                        </label>  
                        <label for="">
                            <div>
                                密码:
                                <input type="text" name='passworld' defaultValue={passworld} onChange={this.handleTest}/>
                                <span className='error'> * {passworldError}</span>
                            </div>
                        </label>  
                        <label for="">
                            <div>
                                性别:
                                <input type="radio" name="sex" value='1' defaultChecked={sex==1? true:false} id="" onChange={this.handleChange}/>男
                                <input type="radio" name="sex" value='2' defaultChecked={sex==2? true:false} id="" onChange={this.handleChange}/>女
                            </div>
                        </label> 
                        <label for="">
                            手机号:<input type="text" name='phone' defaultValue={phone} onChange={this.handleTest}/>
                            <span className='error'> * {phoneError}</span>    
                        </label>  
                        <label for="">
                            <div>
                                城市:
                                <select defaultValue={city} name="city" onChange={this.handleChange}>
                                    {
                                        selectArr.map( (item, index) =>{
                                            return <option value={item.id} key={index}>{item.text}</option>
                                        })
                                    }
                                </select>
                            </div>
                        </label>
                        <label for="">
                            <div>
                                备注:
                                <textarea name="textareaValue" id="" defaultValue={textareaValue}  cols="30" rows="10" onChange={this.handleChange}></textarea>   
                            </div>
                        </label>
                        <button disabled={!name || nameError|| !passworld || passworldError|| !sex || !phone ||phoneError || !city ||!textareaValue } onClick={this.submit }>提交</button>
                    </form>
                </div>
            }
        }
        ReactDOM.render(<Rtx />, document.getElementById('root1'))
    </script>
</body>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/421458.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阿尔卡特Adixen ADP/ADS 系列 2 干泵使用说明

阿尔卡特Adixen ADP/ADS 系列 2 干泵使用说明

JVM 第二部分-2(堆,方法区)

4.堆 堆 一个Java程序&#xff08;main方法&#xff09;对应一个jvm实例&#xff0c;一个jvm实例只有一个堆空间堆是jvm启动的时候就被创建&#xff0c;大小也确定了。大小可以用参数设置。堆是jvm管理的一块最大的内存空间 核心区域&#xff0c;是垃圾回收的重点区域堆可以位…

基于SSM的高校竞赛和考级查询系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的高校竞赛和考级查询系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Sp…

带着问题阅读源码——Spring MVC是如何将url注册到RequestMappingHandlerMapping?

背景 在 Spring MVC 中&#xff0c;DispatcherServlet 是前端控制器&#xff08;front controller&#xff09;&#xff0c;它负责接收所有的 HTTP 请求并将它们映射到相应的处理器&#xff08;handler&#xff09;。为了实现这一点&#xff0c;Spring MVC 使用了适配器模式将…

Atcoder ABC342 E - Last Train

Last Train&#xff08;最后一班火车&#xff09; 时间限制&#xff1a;2s 内存限制&#xff1a;1024MB 【原题地址】 所有图片源自Atcoder&#xff0c;题目译文源自脚本Atcoder Better! 点击此处跳转至原题 【问题描述】 【输入格式】 【输出格式】 【样例1】 【样例输入…

<网络安全>《61 微课堂<第1课 南北向流量是什么?>》

1 形象化解释 在网络安全中&#xff0c;经常听到南北向流量这个词。那究竟是什么意思呢&#xff1f; 这里的南北&#xff0c;就是地图上的东西南北&#xff0c;是方向。我们在画网络架构图时&#xff0c;往往是由上到下依次是web层、应用层、数据层&#xff0c;流量从web层到…

数据结构——跳表

简单介绍跳表 跳表&#xff08;Skip List&#xff09;是一种可以进行对数级别查找的数据结构&#xff0c;它通过在数据中构建多级索引来提高查询效率。跳表是一种基于链表的随机化数据结构&#xff0c;其本质是由多个链表组成&#xff0c;每个链表中的元素都是原始链表中的元素…

图神经网络导论 - 刘知远

一、神经网络基础 近年来&#xff0c;机器学习领域的发展迅速&#xff0c;主要表现在多种神经网络架构的出现。尽管不同的神经网络架构相差甚远&#xff0c;但现有的神经网络架构可以分为几个类别&#xff1a; 卷积神经网路是前馈神经网路的特殊形式&#xff0c;FNN通常是全…

RISC-V特权架构 - 中断与异常概述

RISC-V特权架构 - 中断与异常概述 1 中断概述2 异常概述3 广义上的异常3.1 同步异常3.2 异步异常3.3 常见同步异常和异步异常 本文属于《 RISC-V指令集基础系列教程》之一&#xff0c;欢迎查看其它文章。 1 中断概述 中断&#xff08;Interrupt&#xff09;机制&#xff0c;即…

java实现图片转pdf,并通过流的方式进行下载(前后端分离)

首先需要导入相关依赖&#xff0c;由于具体依赖本人也不是记得很清楚了&#xff0c;所以简短的说一下。 iText&#xff1a;PDF 操作库&#xff0c;用于创建和操作 PDF 文件。可通过 Maven 或 Gradle 引入 iText 依赖。 MultipartFile&#xff1a;Spring 框架中处理文件上传的类…

MyBatis 学习(四)之 SQL 映射文件

目录 1 SQL 映射文件介绍 2 select 元素 3 insert 元素 4 update 和 delete 元素 5 sql 元素 6 parameterType 元素 7 resultType 元素 8 resultMap 元素&#xff08;重要&#xff09; 9 参考文档 1 SQL 映射文件介绍 映射器是 MyBatis 中最复杂并且是最重要的…

机器学习 -- 梯度下降算法加深

梯度下降算法 在机器学习中&#xff0c;梯度下降算法常用于最小化代价函数&#xff08;或损失函数&#xff09;&#xff0c;以此来优化模型的参数。代价函数衡量的是模型预测值与实际值之间的差异。通过最小化这个函数&#xff0c;我们可以找到模型预测最准确的参数。 代价函…

蓝桥杯-单片机组基础6——定时计数器与外部中断混合使用(附小蜜蜂课程代码)

蓝桥杯单片机组备赛指南请查看这篇文章&#xff1a;戳此跳转蓝桥杯备赛指南文章 本文章针对蓝桥杯-单片机组比赛开发板所写&#xff0c;代码可直接在比赛开发板上使用。 型号&#xff1a;国信天长4T开发板&#xff08;绿板&#xff09;&#xff0c;芯片&#xff1a;IAP15F2K6…

Android 混淆是啥玩意儿?

什么是混淆 Android混淆&#xff0c;是伴随着Android系统的流行而产生的一种Android APP保护技术&#xff0c;用于保护APP不被破解和逆向分析。简单的说&#xff0c;就是将原本正常的项目文件&#xff0c;对其类、方法、字段&#xff0c;重新命名a,b,c…之类的字母&#xff0c…

[AutoSar]BSW_Com07 CAN报文接收流程的函数调用

目录 关键词平台说明一、背景二、顺序总览三、函数说明3.1 Com_RxIndication&#xff08;&#xff09; 关键词 嵌入式、C语言、autosar、OS、BSW 平台说明 项目ValueOSautosar OSautosar厂商vector &#xff0c;芯片厂商TI 英飞凌编程语言C&#xff0c;C编译器HighTec (GCC)…

win11安装nodejs

一、下载安装包 链接: https://pan.baidu.com/s/1_df8s1UlgNNaewWrWgI59A?pwdpsjm 提取码: psjm 二、安装步骤 1.双击安装包 2.Next> 3.勾选之后&#xff0c;Next> 4.点击Change&#xff0c;选择你要安装的路径&#xff0c;然后Next> 5.点击Install安装 二、…

MySQL 存储过程批量插入总结

功能需求背景&#xff1a;今天接到产品经理核心业务表的数据压测功能&#xff0c;让我向核心业务表插入百万级的业务量数据&#xff0c;我首先想到的办法就是存储过程实现数据的批量 。 由于无法提供核心业务表&#xff0c;本文仅仅提供我刚刚自己创建的表bds_base_user 表做相…

【Vue3】深入理解Vue中的ref属性

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

VSCode通过SSH连接Docker环境进行开发

文章目录 VSCode 插件Docker 镜像构建镜像部署环境 VSCode 连接本地Docker容器VSCode SSH连接Docker容器VSCode 打开容器内目录文件 VSCode 插件 Remote - SSH Docker 镜像 https://hub.docker.com/_/golang # Golang 镜像 docker pull golang:1.22构建镜像 Dockerfile F…

Shell条件判断

一、文件类型判断 示例&#xff1a; # 判断文件是否存在&#xff0c;存在为0&#xff0c; 不存在为1 [rootlocalhost ~]# test -e person.txt [rootlocalhost ~]# echo $? 0 [rootlocalhost ~]# [rootlocalhost ~]# test -e aba [rootlocalhost ~]# echo $? 1 # 出test外&am…
最新文章