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:[],//文本域的valuetextareaValue:'',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更新checkArrthis.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.statelet {checkboxChange} =thisreturn <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: [],//文本域的valuetextareaValue: '',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更新checkArrthis.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.statelet { checkboxChange } = thisreturn <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.namethis.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.statereturn <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.valuelet 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.valuelet key = e.target.namelet 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.namethis.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.statelet 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.statereturn <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.mzph.cn/news/712993.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

回溯例题(leetcode17/37)

文章目录 leetcode37leetcode17 回溯跟枚举差不多。要注意“回溯”&#xff0c;别忘记“回”之前把之前的改动都复原。 leetcode37 leetcode37是解数独问题。本题保证有且仅有唯一解。 思路&#xff1a;先把空格子的位置存下来&#xff0c;然后对每一个空位置挨个枚举1-9。枚…

Excel常用公式总结非常实用

16个最实用的Excel万能公式 1、多条件判断 IF(And(条件1,条件2..条件N),条件成立返回值) IF(or(条件1,条件2..条件N),条件成立返回值) 2、多条件查找 Lookup(1,0/((条件1*条件2*...条件N)),返回值区域&#xff09; 3、多条件求和 Sumifs(值区域,判断区域1,条件1,判断区域2,条…

Java 数据库面试题解析(下)

20. Hash索引和B树索引的区别&#xff1f;【重点】 hash索引&#xff1a;等值查询效率高&#xff0c;不能排序&#xff0c;不能进行范围查询&#xff1b; B树索引&#xff1a;数据有序&#xff0c;适合范围查询。 21. MySQL中三种锁的级别&#xff1f;【了解】 表级锁&…

2024最新精华版Java面试题之spring篇

目录 一、Java面试题之spring篇 1、什么是spring? 2、你们项目中为什么使用Spring框架&#xff1f; 3、 Autowired和Resource关键字的区别&#xff1f; 4、依赖注入的方式有几种&#xff0c;各是什么? 5、讲一下什么是Spring容器&#xff1f; 6、说说你对Spring MVC的理…

Java毕业设计-基于springboot开发的私人健身与教练预约系统-毕业论文+答辩PPT(有源代码)

文章目录 前言一、毕设成果演示&#xff08;源代码在文末&#xff09;二、毕设摘要展示1.开发说明2.需求分析3、系统功能结构 三、系统实现展示1、系统功能模块2、后台功能模块2.1管理员功能2.2用户功能2.3教练功能 四、毕设内容和源代码获取总结 [Java毕业设计-基于springboot…

Android 11.0 内置google tts语音包功能实现

1.前言 在11.0的系统rom产品开发中,在gms的相关项目对于文字转语音包功能不是内置功能,需要自己下载google的tts语音包,然后内置,在设置 google tts语音包apk作为默认的tts语音引擎功能,接下来分析实现这个功能 2.内置google tts语音包功能实现的核心类 frameworks/ba…

Chat GPT4.0:开启智能对话的新纪元

介绍 Chat GPT4.0是基于GPT4.0架构开发的一款强大的智能对话模型。作为人工智能领域的最新进展&#xff0c;Chat GPT4.0引领着智能对话技术的新纪元。本文将探讨Chat GPT4.0的创新之处以及对智能对话发展的推动作用。 Chat GPT4.0的创新之处 Chat GPT4.0在前一版本的基础上进…

c++知识点之 --引用

本质&#xff1a;给变量起别名 语法&#xff1a;数据类型 &别名 原名 特点&#xff1a;传引用比传值的效率高很多 注意事项&#xff1a; 引用必须初始化&#xff0c;且初始化不能为空。引用不能改变引用关系&#xff08;引用的底层是指针常量&#xff08;type * const …

前端 JS 经典:for-in 和 for-of 用法区别

1. for-in 对于 string, object, array 类型使用 for-in const str "qwe"; const arr ["yqcoder", "db"]; const obj {name: "yqcoder",age: 18, };for (let i in str) {console.log(i); // 0 1 2 } for (let i in arr) {console…

简单数据类型和复杂数据类型

1. 简单数据类型 null是个特例: 2. 复杂数据类型 3. 堆和栈 注意&#xff1a; JavaScript 中是没有堆和栈的概念的&#xff0c;通过堆栈的概念可以更好的理解代码的一些执行方式&#xff0c;便于将来学习其他语言。 4. 简单数据类型传参 总结&#xff1a;简单数据类型传参传…

webview_h5与原生增加权限索取行为交互(Flutter)

应各大应用市场上架要求,增加权限索取行为用户交互弹窗 详细: https://developer.huawei.com/consumer/cn/doc/app/FAQ-faq-05#h1-1698326401789-0 flutter端使用permission_handler申请权限注册一个MethodChannel,增加一个函数,提供安卓webview相机/麦克风等权限被触发时回调…

C++写入和读取结构体到二进制文件

二进制文件速度快&#xff0c;空间效率高 写入数据到二进制文件 #include<iostream> #include<fstream> using namespace std; int main() {// 定义一个结构体struct student{int id; // 学号char name[20]; // 姓名double score; // 成…

LeetCode 2369.检查数组是否存在有效划分:动态规划(DP)

【LetMeFly】2369.检查数组是否存在有效划分&#xff1a;动态规划(DP) 力扣题目链接&#xff1a;https://leetcode.cn/problems/check-if-there-is-a-valid-partition-for-the-array/ 给你一个下标从 0 开始的整数数组 nums &#xff0c;你必须将数组划分为一个或多个 连续 子…

在线ai写作,让你随时随地创作优质内容

如今的ai技术已经渗透到我们生活的方方面面。其中&#xff0c;AI写作成为了一个备受关注的领域。如今&#xff0c;我们可以利用在线ai写作在任何时间、任何地点创作出优质的内容。 传统的写作过程需要大量的时间和精力。从构思到写作再到修改&#xff0c;每一个环节都需要我们投…

Linux进程管理——top字段

目录 1.top下半部分——进程状态 2.top常用内部命令 3.top指定 ①top ②top -d 1 ③top -d 1 -p 10126 ④top -d 1 -p 10126,1 4.使用信号控制进程 1.top下半部分——进程状态 PID&#xff1a;进程号 User&#xff1a;用户 PR/NI&#xff1a;优先级 VIRT&#xff08…

Helm repo 国内镜像配置

微软 http://mirror.azure.cn/kubernetes/charts/ 阿里云 https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts/ 步骤 helm repo add stable http://mirror.azure.cn/kubernetes/charts/ helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/char…

国产软件很流氓?不,这些国产软件良心且实用,别让它们寒心

谈及国产软件&#xff0c;人们常将其与“流氓、捆绑、满屏广告”等负面词汇挂钩。但真实情况是&#xff0c;仍有许多优质国产软件在默默耕耘&#xff0c;它们既免费又实用&#xff0c;别让它们寒了心。 1、Dism Dism是一款专为Windows系统设计的管理优化神器&#xff0c;其开…

ECMAScript 6+ 新特性 ( 六 ) 模块化

2.17. 模块化 模块化是指将一个大的程序文件&#xff0c;拆分成许多小的文件&#xff0c;然后将小文件组合起来。 这样就可以更清晰和结构化的方式组织代码 模块功能主要由两个命令构成&#xff1a;export 和 import export 命令用于规定模块的对外接口 ( 公开 , 暴露) im…

PowerShell 详细介绍

PowerShell 是微软开发的一款功能强大的命令行工具和脚本语言&#xff0c;它基于 .NET Framework 构建&#xff0c;可以帮助系统管理员和开发者自动化各种系统管理和应用程序开发任务。PowerShell 提供了丰富的命令集和脚本功能&#xff0c;可以轻松地管理 Windows 操作系统、应…

呦呵,阿里云果然是良心云

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 你听说了吗?阿里云全线降价20%&#xff0c;还上了热搜。2024年一开年&#xff0c;看来阿里云杀红了眼&#xff0c;云市场即将变天。 现在续费的阿里云主机&#xff0c;续费三年和续费两年的价钱差不多&#xff0…