事件 这里的事件,指的是React内部封装DOM组件中的事件,如onClick,onFocus等,而非我们自己通过props传递的属性,并在子组件中手动触发的事件 实例importReact,{Component}classTodoListextendsComponent{render(){return(inputtypetextbuttononClick{(){alert(1)}}addbuttonbuttononClick{this。handelClick}add2buttonbuttononClick{this。handelClick2}add3buttonbuttononClick{(){this。handelClick3()}}add4button);}handelClick(){console。log(1)console。log(this)}箭头函数handelClick2(){console。log(2)console。log(this)}箭头函数handelClick3(){console。log(3)console。log(this)}}exportdefaultTodoLreact事件声明1。react事件采用驼峰式命名2。react事件接收一个函数声明,不是函数调用的形式原生react绑定事件 采用on事件名的方式来绑定一个事件。 注意,这里和原生的事件是有区别的: 原生的事件全是小写onclick,React里的事件是驼峰onClick,React的事件并不是原生事件,而是合成事件。事件handler的写法直接在render里写行内的箭头函数(不推荐)在组件内使用箭头函数定义一个方法(推荐)直接在组件内定义一个非箭头函数的方法,然后在render里直接使用onClick{this。handleClick。bind(this)}(不推荐)直接在组件内定义一个非箭头函数的方法,然后在constructor里bind(this)(推荐)Event对象 和普通浏览器一样,事件handler会被自动传入一个event对象,这个对象和普通的浏览器event对象所包含的方法和属性都基本一致。不同的是React中的event对象并不是浏览器提供的,而是它自己内部所构建的。它同样具有event。stopPropagation、event。preventDefault这种常用的方法。this问题 实例importReact,{Component}classTodoListextendsComponent{render(){return(inputtypetext{:如果逻辑过不多,此写法推荐}{可以直接访问this,无需手动绑定}buttononClick{(){console。log(0)console。log(this)}}addbutton{:此写法不推荐}{不可以直接访问this,需手动绑定。bind(this)}buttononClick{this。handelClick。bind(this)}add2button{:此写法推荐}{可以直接访问this,无需手动绑定,handelClick2是箭头函数,可以绑定外部this:此写法推荐}buttononClick{this。handelClick2}add3button{:此写法比较推荐,传参数很方便}{可以直接访问this,无需手动绑定,onClick调用的是箭头函数,可以绑定外部this}buttononClick{(e)this。handelClick3(e)}add4button);}handelClick(){console。log(1)console。log(this)}箭头函数handelClick2(evt){console。log(2)console。log(this)打印Event对象console。log(evt)}箭头函数handelClick3(evt){console。log(3)打印Event对象console。log(evt)}}exportdefaultTodoL 为什么使用bind绑定this class组件的事件绑定this问题1。class的方法默认不会绑定this,如果没有绑定this。handleClick的this并把它传入了onClick,当你调用这个函数的时候this的值为undefined。classAextendsReact。Component{constructor(props){super(props)}handleClick(){class的方法默认不会绑定this,this的指向根据调用的方式判断没有绑定调用的话this为undefinedthis。setState({a:1})}render(){return()}} this问题的解决方式有三种 (1)在constructor里使用bind为方法绑定thisclassAextendsReact。Component{constructor(props){super(props)this。handleClickthis。handleClick。bind(this);注意此处}handleClick(){this。setState({a:1})}} (2)在元素上绑定事件时使用箭头函数classAextendsReact。Component{constructor(props){super(props)}handleClick(){class的方法默认不会绑定this,this的指向根据调用的方式判断没有绑定调用的话this为undefinedthis。setState({a:1})}render(){render里的this指向自身return(this。handleClick()})}} (3)使用箭头函数声明方法classAextendsReact。Component{constructor(props){super(props)}handleClick(){箭头函数的this由父作用域的this判断this。setState({a:1})}render(){render里的this指向自身return()}}react事件传递参数1。要在绑定事件的位置给事件传参有两种方式, (1)通过bind,使用bind会隐式传入事件对象e,作为函数的最后一个参数。buttononClick{this。deleteRow。bind(this,id)}DeleteRowbutton (2)通过箭头函数,使用箭头函数需要主动传入事件对象e。buttononClick{(e)this。deleteRow(id,e)}DeleteRowbuttonbuttononClick{this。deleteRow。bind(this,id)}DeleteRowbutton事件说明 React根据W3C规范定义了合成事件(SyntheticEvent),我们就无需担心跨浏览器的兼容性问题React出于性能与事件管理方面的考量,在之前的React版本中(v17之前)会将在JSX中注册的事件收集到document上(即通过事件委托,在document上注册事件,等触发事件时,则按虚拟DOM树的结构进行事件触发机制去分发事件);几乎所有的事件处理,均在document的事件中处理比如onFocus等事件不会冒泡的事件,就不做委托,直接在元素上监听一些document上没有的事件,也直接在元素上监听(如:audio、video标签的事件等)在document中的事件处理,会根据虚拟DOM树的结构完成事件函数的调用,默认是冒泡机制(事件捕获要通过类似onClickCapture的方式注册)React的事件参数,并非真实的事件参数,而是React合成的一个对象(SyntheticEvent)通过调用e。stopPropagation()阻止事件冒泡(仅阻止React事件)通过e。nativeEvent可以得到真实的DOM事件对象(不过很少会用到)为了提高效率,React使用事件对象池来处理事件对象(即事件对象会重用)在React17之后,事件委托的节点就转移到了渲染的根节点上,而且也帮我们解决了此类关于事件冒泡的问题(本文测试用例则说明,对于使用ReactDOM。createPortal创建的组件,表现上略有差异) 注意点若给真实DOM注册事件,并阻止冒泡,则很有可能导致React(JSX)中注册的相关事件无法触发若给真实DOM注册事件,它会先于React事件执行(即通过onClick和dom。addEventListener绑定的事件,真实DOM事件会先执行;因为这个元素被点击时,真实DOM事件会很快找到,而React绑定的事件则需要去找到事件委托的元素,再去调用当前点击元素绑定的事件函数)过React事件阻止事件冒泡,无法阻止真实DOM事件的冒泡可以使用e。nativeEvent。stopImmediatePropagation()去阻止document上剩余的事件处理程序的运行(当我们在使用某些第三方库,在这个库有可能使用了一些事件处理,也对document绑定过点击事件,如:document。addEventListener(click,handler))在事件处理程序中,不要异步使用事件对象e;如果一定有异步使用的需求,则需要调用e。persist()函数持久化保存此事件对象(代价自然是损耗效率的)React事件总结绑定事件处理函数1。1鼠标类1。onContextMenu2。onClick3。onDoubleClick4。onMouseDown5。onMouseUp6。onMouseEnter7。onMouseLeave8。onMouseMove9。onMouseOut10。onMouseOver1。2拖拽事件:1。onDrop2。onDrag3。onDragStart4。onDragEnd5。onDragEnter6。onDragLeave7。onDragOver8。onDragExit1。3触摸 触摸只会在移动设备上产生1。onTouchStart2。onTouchEnd3。onTouchMove4。onTouchCancel1。4键盘 onKeyPress是onKeyDown和onKeyUp的组合1。onKeyPress2。onKeyDown3。onKeyUp剪切类 对应的是我们常常使用的复制、剪切和粘贴1。onCopy2。onCut3。onPaste表单类1。onChange2。onInput3。onSubmit4。onChange可以用在输入框、单选框、下拉列表里,每当内容发生变化时我们都能获得通知。 onInput使用在文字输入。 onSubmit是用在整个表单的输入提交,常用在禁止表单的默认操作。1。7焦点事件1。onFocus2。onBlur1。8UI元素类1。onScroll 滚动事件触发的时候会触发onScroll事件1。9滚动1。onWheel 鼠标滚轮触发的事件,监听滚动幅度,滚动方位1。10组成事件1。onCompositionEnd2。onCompositionStart3。onCompositionUpdate1。11图片类1。onLoad2。onError1。12多媒体类1。onAbort2。onCanPlay3。onCanPlayThrough4。onDurationChange5。onEmptied6。onEncrypted7。onEnded8。onError9。onLoadedData10。onLoadedMetadata11。onLoadStart12。onPause13。onPlay14。onPlaying15。onProgress16。onRateChange17。onSeeked18。onSeeking19。onStalled20。onSuspend21。onTimeUpdate22。onVolumeChange23。onWaiting事件池 虚拟事件对象已经被合并。这意味着虚拟事件对象将被重新使用,而该事件回调被调用之后所有的属性将无效。这是出于性能的考虑。因此,您不能以异步的方式访问事件。functiononClick(event){console。log(event);无效的对象console。log(event。type);clickvareventTypeevent。clicksetTimeout(function(){console。log(event。type);nullconsole。log(eventType);click},0);this。setState({clickEvent:event});不起作用。this。state。clickEvent将只包含空值。this。setState({eventType:event。type});您依然可以导出事件属性} 如果您想以一个异步的方式来访问事件属性,您应该对事件调用event。persist()。这将从事件池中取出合成的事件,并允许该事件的引用,使用户的代码被保留。事件对象 事件处理器将会传入SyntheticEvent的实例,一个对浏览器本地事件的跨浏览器封装。它有和浏览器本地事件有相同的属性和方法,包括stopPropagation()和preventDefault(),但是没有浏览器兼容问题。 如果因为一些因素,需要底层的浏览器事件对象,只要使用nativeEvent属性就可以获取到它了。 对于v0。14,在事件处理函数中返回false将不会阻止事件冒泡。取而代之的是在合适的应用场景下,手动调用e。stopPropagation()或者e。preventDefault()。handleChange:function(e){console。log(e。target。value);} 其中target是事件对象e是事件对象的属性通用属性 (以下内容括号内为类型)1。bubbles(boolean)表示事件是否冒泡2。cancelable(boolean)表示事件是否可以取消3。currentTarget(DOMEventTarget)与Target类似,由于事件可以冒泡,所以两者表示的内容是不同的4。defaultPrevented(boolean)表示事件是否禁止了默认行为5。eventPhase(number)表示事件所处的阶段6。isTrusted(boolean)表示事件是否可信。所谓的可信事件表示的是用户操作的事件,不可信事件就是通过JS代码来触发的事件。7。nativeEvent(DOMEvent)8。preventDefault()(void)对应的defaultPrevented,表示的是禁止默认行为9。stopPropagaTion()(void)对应的是bubbles,表示的是sh10。target(DOMEventTarget)11。timeStamp(number)时间戳,也就是事件触发的事件12。type(string)事件的类型不同事件对象的特有属性剪切事件1。clipboardData(DOMDataTransfer)表示拿到的数据键盘事件1。ctrlKey(boolean)表示是否按下ctrl键2。altKey(boolean)表示是否按下alt键3。shiftKey(boolean)表示是否按下shift4。metaKey(boolean)表示的是win系统下的win键,mac系统下对应的command键5。getModifierState(key)(function)表示是否按下辅助按键(辅助按键就是雷士ctrl、shift等辅助按键)可以传入按键编码来判断是否按下6。charCode(Number)表示的是按键的字符编码,可以通过编码来判断按下的是什么键7。key(string)字符串,按下的键8。keyCode(Number)表示那些不是字符编码的按键9。which(Number)表示经过通用化得charCode和keyCode10。locale(String)表示本地化得一些字符串11。location(number)表示位置12。repeat(boolean)表示按键是否重复焦点事件1。relatedTarget(DOMEventTarget)相关焦点对象鼠标事件1。ctrlKey(boolean)2。altKey(boolean)3。shiftKey(boolean)4。metaKey(boolean)5。getModifierState(key)(function)6。button(Number)7。buttons(Number)8。clientX(Number)原点为浏览器左上角9。clinetY(Number)原点为浏览器左上角10。pageX(Number)原点为HTML页面的左上角11。pageY(Number)原点为HTML页面的左上角12。screenX(Number)原点为显示器的左上角13。screenY(Number)原点为显示器的左上角14。relatedTarget(DOMEventTarget)触摸事件 为了使触摸事件生效,在渲染所有组件之前调用React。initializeTouchEvents(true)。1。ctrlKey(boolean)2。altKey(boolean)3。shiftKey(boolean)4。metaKey(boolean)5。getModifierState(key)6。changedTouches(DOMTouchList)判断手势操作7。targetTouches(DOMTouchList)判断手势操作8。touches(DOMTouchList)判断手势操作UI元素事件1。detail(Number)滚动的距离2。view(DOMAbstractView)界面,视窗鼠标滚动1。deltaMode(Number)可以理解为移动的单位2。deltaX(Number)X轴移动的相对距离固定值3。deltaY(Number)Y轴移动的相对距离固定值4。deltaZ(Number)Z轴移动的相对距离固定值实例滚动事件对象varHelloDadaReact。creatClass({getInitialState:function(){return{backgroundColor:FFFFFF}},handleWheel:function(e){varnewColor(parseInt(this。state。backgroundColor。substr(1),16)e。deltaY997)。tiString(16);this。setState({backgroundColor:newColor})},render:function(){return注意这里onWheelpDadaShuaige}});ReactDOM。render(HelloDada,document。body)键盘事件对象varDadaReact。creatClass{getInitialState:function(){return{password:}},handleKeyPress:function(e){this。setState({paddword:this。state。passworde。which});},handleChange:function(e){e。target。},render:function(){returninputonKeyPress{this。handleKeyPress}onChange{this。handleChange}注意这里onKeyPresspstyle{{display:this。state。password。indexOf(495051)0?block:none}}Dadahandsomeboy}};ReactDOM。render(Dada,document。body)事件与状态关联 状态不仅仅实现了组件内部结果的清晰对应,还实现了组件与用户之间的交互,使用户与组件的行为紧紧结合起来handleChange:function(e){this。setState({Dada:e。target。value});} this。setState设置状态 实例varDadaReact。creatClass({getInitialState:function(){return{x:0,y:0}},handleMouseMove:function(e){this。setState({x:e。clientX,y:e。clientY});},render:function(){return{this。state。x。this。state。y}}});ReactDOM。render(Dada,document。body)React绑定事件和原生绑定事件的区别 react事件和原生事件的区别是:react中的事件是绑定到document上面,React并不会真正的绑定事件到每一个具体《》的元素上,而是采用事件代理的模式:而原生的事件是绑定到dom上面。 相对绑定的地方来说,dom上的事件要优先于document上的事件执行,react的事件对象是合成。 参考链接:https:blog。csdn。netqq40340943articledetails107309779https:www。bbsmax。comAGkz1PBOgdR