玩转Reactjs第五篇-基础知识(事件条件列表表单)

2024-03-20 10:18

本文主要是介绍玩转Reactjs第五篇-基础知识(事件条件列表表单),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、前言

其实在前面介绍组件的时候,已经用到了这些知识,本章节我们重点分析下,并与Vue的用法比较。

二、事件

    Reactjs中事件处理方式与原生态DOM的非常类似,只不过使用JSX的语法,采用的是小驼峰的表达方式,比如onClick,onChange,我们以SearchHot.js的"下一批"功能为例,当点击按钮,更新热词。

return (<div className="d"> <div className="s">大家都在搜:<a href="#" onClick={this.changeHot} style={{marginLeft:100}}>下一批</a></div><ul className="su">{/*引用变量表达式  */}{hotList}</ul></div> )

在a标签上增加onClick响应事件,调用的方法为changeHot,下面我们对该方法定义

changeHot(){this.setState({hotItem:['电视','手机','电脑','平板']})}

在此方法中,我们调用setState更新hotItem属性。如果直接运行,将会报this为undefined的错误,我们还需要在组件初始化方法中,将该方法绑定到组件对象。

constructor(props){// 1、调用父类构造方法super(props);//2、初始化state对象this.state = {hotItem:['口罩','手套','酒精',]};//绑定thisthis.changeHot = this.changeHot.bind(this);}

除了这种bind方式,还可以将changeHot改造为箭头函数,在箭头函数中,this指向的函数的本身,而不是函数的调用者,可以参考ES6系列教程第八篇--箭头函数详解

changeHot = () =>this.setState({hotItem:['电视','手机','电脑','平板']});

我们在a标签上增加一个默认事件,href="search.json"

return (<div className="d"> <div className="s">大家都在搜:<a href="search.json" onClick={this.changeHot} style={{marginLeft:100}}>下一批</a></div><ul className="su">{/*引用变量表达式  */}{hotList}</ul></div> )

此时再次点击按钮,发现页面跳转到search.json,这是因为执行了默认事件。现在我们需要阻止默认事件或者冒泡。

changeHot(e){e.preventDefault();e.stopPropagation();this.setState({hotItem:['电视','手机','电脑','平板'] })}

再次点击时,功能正常。

事件方法中会隐形传入一个event参数,通过调用该参数的preventDefault(),stopPropagation()阻止默认事件以及冒泡。

传参是事件的基本的功能,我们看下React如何实现传参。

return (<div className="d"> <div className="s">大家都在搜:<a href="search.json" onClick={this.changeHot.bind(this,1,"ok")} style={{marginLeft:100}}>下一批</a></div><ul className="su">{/*引用变量表达式  */}{hotList}</ul></div> )

在调用的时候绑定this对象,并依次传递相关的参数(注意:事件方法已经绑定了this,可以不需要再在初始化方法中重复绑定),在changeHot中接受并处理参数。

changeHot(id,name,e){e.preventDefault();e.stopPropagation();this.setState({hotItem:['电视','手机','电脑','平板'] });console.log("id:"+id);console.log("name:"+name)}

无论传递多少参数,隐形的event参数始终处于最后的位置。

在Vue中,事件的处理使用的是v-on内置的指令,并通过事件的修饰符简化了诸如阻止默认事件,冒泡等写法。而JSX语法中没有指令的概念,其处理方式更接近原生的DOM。

三、条件

在前面章节中,我们介绍JSX仅支持三目以及&&符运算的嵌入,而不支持if...else条件语句。我们先看三目运算和&&。

在SearchBox.js中,我们用this.state.isSearch标志符控制button按钮的disabled属性,当this.state.isSearchShow为true,按钮有效,false则无效。

        return(<div style={{width:300,margin:10}}><input type="text" style={{width:150}} onChange={this.handleChange}></input>&nbsp;&nbsp;<button onClick={this.onSearchClick} disabled={this.state.isSearchShow?"":"disabled"}>搜索</button></div>)

也可以改写&&运算

return(<div style={{width:300,margin:10}}><input type="text" style={{width:150}} onChange={this.handleChange}></input>&nbsp;&nbsp;<button onClick={this.onSearchClick} disabled={!this.state.isSearchShow&&"disabled"}>搜索</button></div>)

在js中,true && expression 总是会返回 expression, 而 false && expression 总是会返回 false。

如果是多个条件组合,三目运算就无法满足了,比如不同的状态,显示button的不同背景色,此时就需要用到if...else。

render(){//定义color变量,并根据状态显示不同的颜色let color;if(this.state.color<10){color="green"}else if(this.state.color<20){color="blue"}else if(this.state.color<30){color="red"}else{color="orange"}return(<div style={{width:300,margin:10}}><input type="text" style={{width:150}} onChange={this.handleChange}></input>&nbsp;&nbsp;<button onClick={this.onSearchClick} disabled={!this.state.isSearchShow&&"disabled"} style={{backgroundColor:color}}>搜索</button></div>)}

虽然JSX中无法直接使用if...else,但可以通过在代码段中,定义color的变量并条件赋值,再在JSX中插入color变量表达式。

在Vue中使用v-if,v-else指令进行条件控制,并对控件的隐藏和显示提供了v-show,使用更方便。

四、列表

Reactjs中对于列表使用map方法进行遍历,并拼装成JSX表达式。以SearchList.js的搜索结果列表展示为例:

render(){//1、从props中获取searchListVal,封装列表const searchValList = this.state.searchListVal.map((value)=>(<li>{value}</li>));return(<div className="d"><div className="s">搜索结果:</div>{/* 引入插槽代码 */}{this.props.children}<ul className="u" ref={this.searchul}>{/* 引用对象表达式*/}{searchValList}</ul></div>       )}

遍历searchListVal数组,拼装li表达式。此时我们打开控制台,会发现有如下的warning

这个告警的意思,list应增加一个key属性。

 const searchValList = this.state.searchListVal.map((value)=>(<li key={value.toString()}>{value}</li>));

告警消失,那加上这个key有什么作用呢?

这要从diff算法的原理说起。diff运算时,对于同一节点下的子元素,进行遍历比较,如果不一致,则产出一个mutation。如下:

//老节点
<ul><li>first</li><li>second</li>
</ul>
//新节点
<ul><li>first</li><li>second</li><li>third</li>
</ul>

该样例中,ul的子元素li,新老节点中第一个和第二个是完全一样的,所以无需变动,仅在尾部插入第三个li元素,就可以完成节点的更新,效率很高。如果是头部插入一个li呢?

/老节点
<ul> <li>first</li><li>second</li>
</ul>
//新节点
<ul><li>third</li><li>first</li><li>second</li>
</ul>

在diff运算过程中,比较发现第一个,第二个li元素不一样(老节点的第一个为first,新节点的第一个为third),将会销毁重建,效率会非常低。效率最高的的更新操作,仅在头部插入一个third,其他节点保持不变。为了解决这个问题,引入了key。

/老节点
<ul> <li key="1">first</li><li key="2">second</li>
</ul>
//新节点
<ul><li key="3">third</li><li key="1">first</li><li key="2">second</li>
</ul>

diff运算过程中,不是直接遍历比较,而是优先查找是否有相同的key,新老节点都有key为1,2的li元素,且值没有变化,这两个节点将保持不变,最终仅在头部插入key为3的li元素,实现了高效率的更新。

所以,key需要有以下两个特点:

  • key一定是在同级的兄弟节点间设置,因为非同级节点不会进行diff运算。
  • key的值在兄弟节点间必须唯一,一般用id等,最好不要用列表索引(索引可能会变化)

在Vue用使用v-for进行列表渲染,其中也需要设置key,原理是一致的。

五、表单

表单标签包括select,input,textarea,checkbox,radio等,他们是最能说明双向绑定的过程,比如SearchBox.js中的搜索输入框input

handleChange(e){this.setState({searchVal:e.target.value});}
....
return(<div style={{width:300,margin:10}}><input type="text" style={{width:150}} onChange={this.handleChange} value={this.state.searchVal}></input>&nbsp;&nbsp;<button onClick={this.onSearchClick} >搜索</button></div>)

input框的每次输入,通过onChange捕捉变化事件,并响应handleChange方法,将input的当前值更新到state中的searchVal(这就是view->model过程);searchVal赋值给input的value,searchVal值的变化,又反馈到input的value(这就是model->view)。有同学会问,这这么做不是多此一举么,其实不然,在实际使用过程中,我们会在handleChange中对输入值e.target.value进行处理,比如说银行卡号,4个数字一组,做分割处理,再设置给input框输出展示。

Reactjs还提供一种操作DOM获取input的输入值的方式,即使用ref。

首先在构造函数中定义ref

 constructor(props){super(props);this.state = {searchVal:"",isSearchShow:true,color:25};this.onSearchClick = this.onSearchClick.bind(this);this.handleChange = this.handleChange.bind(this); //定义refthis.input = React.createRef();}

然后设置input的ref属性

 return(<div style={{width:300,margin:10}}><input type="text" style={{width:150}} onChange={this.handleChange} ref={this.input} value={this.state.searchVal}></input>&nbsp;&nbsp;<button onClick={this.onSearchClick} >搜索</button></div>)

就可以使用ref获取input的对象句柄,比如handleChange通过ref的方式获取input的值

handleChange(e){this.setState({searchVal:this.input.current.value});}

使用的时候别忘了current关键字。此时input可以通过ref进行DOM操作,称为非受控组件。虽然这种模式打破了数据驱动view的原则,但是有时候还是比较方便的,比如获取滚动条的高度。

在Vue中可有类似的做法,通过自定义的指令操控DOM节点。

六、总结

本章节介绍了Reactjs的事件,条件,列表,表单的基本用法,并与vue进行了简单的比较。

事件的隐形event参数的使用,阻止默认事件以及冒泡,传递参数。

条件的三目运算,&&符,以及if...else条件的使用

列表使用map遍历,以及key的原理。

表单的两种不同的获取对象值的方法。

这篇关于玩转Reactjs第五篇-基础知识(事件条件列表表单)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/829144

相关文章

linux-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

禁止平板,iPad长按弹出默认菜单事件

通过监控按下抬起时间差来禁止弹出事件,把以下代码写在要禁止的页面的页面加载事件里面即可     var date;document.addEventListener('touchstart', event => {date = new Date().getTime();});document.addEventListener('touchend', event => {if (new

计组基础知识

操作系统的特征 并发共享虚拟异步 操作系统的功能 1、资源分配,资源回收硬件资源 CPU、内存、硬盘、I/O设备。2、为应⽤程序提供服务操作系统将硬件资源的操作封装起来,提供相对统⼀的接⼝(系统调⽤)供开发者调⽤。3、管理应⽤程序即控制进程的⽣命周期:进程开始时的环境配置和资源分配、进程结束后的资源回收、进程调度等。4、操作系统内核的功能(1)进程调度能⼒: 管理进程、线

c++的初始化列表与const成员

初始化列表与const成员 const成员 使用const修饰的类、结构、联合的成员变量,在类对象创建完成前一定要初始化。 不能在构造函数中初始化const成员,因为执行构造函数时,类对象已经创建完成,只有类对象创建完成才能调用成员函数,构造函数虽然特殊但也是成员函数。 在定义const成员时进行初始化,该语法只有在C11语法标准下才支持。 初始化列表 在构造函数小括号后面,主要用于给

HTML提交表单给python

python 代码 from flask import Flask, request, render_template, redirect, url_forapp = Flask(__name__)@app.route('/')def form():# 渲染表单页面return render_template('./index.html')@app.route('/submit_form',

go基础知识归纳总结

无缓冲的 channel 和有缓冲的 channel 的区别? 在 Go 语言中,channel 是用来在 goroutines 之间传递数据的主要机制。它们有两种类型:无缓冲的 channel 和有缓冲的 channel。 无缓冲的 channel 行为:无缓冲的 channel 是一种同步的通信方式,发送和接收必须同时发生。如果一个 goroutine 试图通过无缓冲 channel

Spring+MyBatis+jeasyui 功能树列表

java代码@EnablePaging@RequestMapping(value = "/queryFunctionList.html")@ResponseBodypublic Map<String, Object> queryFunctionList() {String parentId = "";List<FunctionDisplay> tables = query(parent

form表单提交编码的问题

浏览器在form提交后,会生成一个HTTP的头部信息"content-type",标准规定其形式为Content-type: application/x-www-form-urlencoded; charset=UTF-8        那么我们如果需要修改编码,不使用默认的,那么可以如下这样操作修改编码,来满足需求: hmtl代码:   <meta http-equiv="Conte

js异步提交form表单的解决方案

1.定义异步提交表单的方法 (通用方法) /*** 异步提交form表单* @param options {form:form表单元素,success:执行成功后处理函数}* <span style="color:#ff0000;"><strong>@注意 后台接收参数要解码否则中文会导致乱码 如:URLDecoder.decode(param,"UTF-8")</strong></span>

java常用面试题-基础知识分享

什么是Java? Java是一种高级编程语言,旨在提供跨平台的解决方案。它是一种面向对象的语言,具有简单、结构化、可移植、可靠、安全等特点。 Java的主要特点是什么? Java的主要特点包括: 简单性:Java的语法相对简单,易于学习和使用。面向对象:Java是一种完全面向对象的语言,支持封装、继承和多态。跨平台性:Java的程序可以在不同的操作系统上运行,称为"Write once,