react之事件处理

这篇具有很好参考价值的文章主要介绍了react之事件处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

事件

这里的事件,指的是 React 内部封装 DOM 组件中的事件,如 onClick, onFocus等,而非我们自己通过 props 传递的属性,并在子组件中手动触发的事件

实例

import React, { Component } from 'react';

class TodoList extends Component {
    render() {
        return (
            <div>
                <input type="text" />
                
                <button onClick={()=>{
                    alert(1)
                }}>add</button>

                <button onClick={this.handelClick}>add2</button>
                
                <button onClick={this.handelClick2}>add3</button>

                <button onClick={()=>{
                   this.handelClick3()
                }}>add4</button>
            </div>
        );
    }

    handelClick () {
        console.log(1)
        console.log(this)
    }

    // 箭头函数 
    handelClick2 = () => {
        console.log(2)
        console.log(this)
    }

    // 箭头函数 
    handelClick3 = () => {
        console.log(3)
        console.log(this)
    }
}

export default TodoList;

react事件声明

  1. react事件采用驼峰式命名
  2. react事件接收一个函数声明不是函数调用的形式
//原生
<div onclick="handleClick()"></div>
//react
<div onClick={this.handleClick}></div>

绑定事件

采用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问题

实例

import React, { Component } from 'react';

class TodoList extends Component {
    render() {
        return (
            <div>
                <input type="text" />

                {/* :如果逻辑过不多,此写法推荐 */}
                {/* 可以直接访问this,无需手动绑定 */}
                <button onClick={()=>{ 
                     console.log(0)
                     console.log(this)
                }}>add</button>

                {/* :此写法不推荐 */}
                {/* 不可以直接访问this,需手动绑定 --  .bind(this)*/}
                <button onClick={this.handelClick.bind(this)}>add2</button>
                
                {/* :此写法推荐 */}
                {/* 可以直接访问this,无需手动绑定,handelClick2是箭头函数,可以绑定外部this :此写法推荐 */}
                <button onClick={this.handelClick2}>add3</button>

                {/* :此写法比较推荐,传参数很方便 */}
                {/* 可以直接访问this,无需手动绑定,onClick调用的是箭头函数,可以绑定外部this */}
                <button onClick={(e)=> this.handelClick3(e)}>add4</button>
            </div>
        );
    }

    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)
    }
}

export default TodoList;

为什么使用bind绑定this

react点击事件,前端杂货铺,react.js,javascript,前端

class组件的事件绑定this问题

1. class的方法默认不会绑定 this,如果没有绑定 this.handleClick的this 并把它传入了 onClick,当你调用这个函数的时候 this 的值为 undefined。
class A extends React.Component{
	constructor(props){
		super(props)	
	}
	handleClick(){
		//class的方法默认不会绑定 `this`,this的指向根据调用的方式判断
		//没有绑定调用的话this为undefined
		this.setState({a:1})
	}
	render(){
		return (
		<div onClick={this.handleClick}></div>
		)
	}
}

this问题的解决方式有三种

(1)在constructor里使用bind为方法绑定this

class A extends React.Component{
	constructor(props){
		super(props)
		this.handleClick= this.handleClick.bind(this);	// 注意此处
	}
	handleClick(){
		this.setState({a:1})
	}
}

(2)在元素上绑定事件时使用箭头函数


class A extends React.Component{
	constructor(props){
		super(props)	
	}
	handleClick(){
		//class的方法默认不会绑定 `this`,this的指向根据调用的方式判断
		//没有绑定调用的话this为undefined
		this.setState({a:1})
	}
	render(){
		//render里的this指向自身
		return (
		<div onClick={()=> this.handleClick() }></div>
		)
	}
}

(3)使用箭头函数声明方法

class A extends React.Component{
	constructor(props){
		super(props)	
	}
	handleClick=()=>{
		//箭头函数的this由父作用域的this判断
		this.setState({a:1})
	}
	render(){
		//render里的this指向自身
		return (
		<div onClick={this.handleClick}></div>
		)
	}
}

react事件传递参数

1.要在绑定事件的位置给事件传参有两种方式,

(1)通过bind,使用bind会隐式传入事件对象e,作为函数的最后一个参数。

<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

(2)通过箭头函数,使用箭头函数需要主动传入事件对象e 。

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

事件说明

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 使用事件对象池来处理事件对象 (即事件对象会重用)
  • 在 React 17 之后,事件委托的节点就转移到了渲染的根节点上,而且也帮我们解决了此类关于事件冒泡的问题 (本文测试用例则说明,对于使用 ReactDOM.createPortal 创建的组件,表现上略有差异)

注意点

  • 若给真实 DOM 注册事件,并阻止冒泡,则很有可能导致 React (JSX) 中注册的相关事件无法触发
  • 若给真实 DOM 注册事件,它会先于 React 事件执行 (即通过 onClickdom.addEventListener 绑定的事件,真实 DOM 事件会先执行;因为这个元素被点击时,真实 DOM 事件会很快找到,而 React 绑定的事件则需要去找到事件委托的元素,再去调用当前点击元素绑定的事件函数)
  • 过 React 事件阻止事件冒泡,无法阻止真实 DOM 事件的冒泡
  • 可以使用 e.nativeEvent.stopImmediatePropagation() 去阻止 document 上剩余的事件处理程序的运行 (当我们在使用某些第三方库,在这个库有可能使用了一些事件处理,也对 document 绑定过点击事件,如: document.addEventListener("click", handler))
  • 在事件处理程序中,不要异步使用事件对象 e;如果一定有异步使用的需求,则需要调用e.persist()函数持久化保存此事件对象 (代价自然是损耗效率的)

React 事件总结

绑定事件处理函数

1.1 鼠标类
  1. onContextMenu
  2. onClick
  3. onDoubleClick
  4. onMouseDown
  5. onMouseUp
  6. onMouseEnter
  7. onMouseLeave
  8. onMouseMove
  9. onMouseOut
  10. onMouseOver
1.2 拖拽事件:
  1. onDrop
  2. onDrag
  3. onDragStart
  4. onDragEnd
  5. onDragEnter
  6. onDragLeave
  7. onDragOver
  8. onDragExit
1.3 触摸

触摸只会在移动设备上产生

  1. onTouchStart
  2. onTouchEnd
  3. onTouchMove
  4. onTouchCancel
1.4 键盘

onKeyPress是onKeyDown和onKeyUp的组合

  1. onKeyPress
  2. onKeyDown
  3. onKeyUp
剪切类

对应的是我们常常使用的复制剪切粘贴

  1. onCopy
  2. onCut
  3. onPaste
表单类
  1. onChange
  2. onInput
  3. onSubmit
  4. onChange可以用在输入框、单选框、下拉列表里,每当内容发生变化时我们都能获得通知。

onInput使用在文字输入。

onSubmit是用在整个表单的输入提交,常用在禁止表单的默认操作。

1.7 焦点事件
  1. onFocus
  2. onBlur
1.8 UI元素类
  1. onScroll

滚动事件触发的时候会触发onScroll事件

1.9 滚动
  1. onWheel

鼠标滚轮触发的事件,监听滚动幅度,滚动方位

1.10 组成事件
  1. onCompositionEnd
  2. onCompositionStart
  3. onCompositionUpdate
1.11 图片类
  1. onLoad
  2. onError
1.12 多媒体类
  1. onAbort
  2. onCanPlay
  3. onCanPlayThrough
  4. onDurationChange
  5. onEmptied
  6. onEncrypted
  7. onEnded
  8. onError
  9. onLoadedData
  10. onLoadedMetadata
  11. onLoadStart
  12. onPause
  13. onPlay
  14. onPlaying
  15. onProgress
  16. onRateChange
  17. onSeeked
  18. onSeeking
  19. onStalled
  20. onSuspend
  21. onTimeUpdate
  22. onVolumeChange
  23. onWaiting

事件池

虚拟事件对象已经被合并。这意味着虚拟事件对象将被重新使用,而该事件回调被调用之后所有的属性将无效。这是出于性能的考虑。因此,您不能以异步的方式访问事件。

function onClick(event) {
  console.log(event); // =>无效的对象
  console.log(event.type); // => "click"
  var eventType = event.type; // => "click"

  setTimeout(function() {
    console.log(event.type); // => null
    console.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,表示的是sh
  10. target(DOMEventTarget)
  11. timeStamp(number) 时间戳,也就是事件触发的事件
  12. type(string) 事件的类型
不同事件对象的特有属性
剪切事件
  1. clipboardData(DOMDataTransfer)表示拿到的数据
键盘事件
  1. ctrlKey(boolean) 表示是否按下ctrl键
  2. altKey(boolean) 表示是否按下alt键
  3. shiftKey(boolean) 表示是否按下shift
  4. 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和keyCode
  10. 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轴移动的相对距离固定值

实例

滚动事件对象
var HelloDada = React.creatClass({
    getInitialState:function(){
        return {
            backgroundColor:'#FFFFFF'
        }
    },
    handleWheel:function(e){
        var newColor = (parseInt(this.state.backgroundColor.substr(1),16)+e.deltaY*997).tiString(16);
        this.setState({
            backgroundColor:newColor
        })
    },
    render:function(){
        return <div onWheel={this.handleWheel} style={this.state}> // 注意这里 onWheel
        <p>Dada Shuaige</p> 
        </div>
    }
});
ReactDOM.render(<HelloDada />,document.body)
键盘事件对象
var Dada =React.creatClass{
    getInitialState:function(){
        return{
            password:''
        }
    },
    handleKeyPress:function(e){
        this.setState({
            paddword:this.state.password+e.which
        });
    },
    handleChange:function(e){
        e.target.value='';
    },
    render:function(){
        return <div>
        <input onKeyPress={this.handleKeyPress} onChange={this.handleChange} /> // 注意这里 onKeyPress
        <p style={{
            'display':this.state.password.indexOf('495051') >=0?'block':'none'
        }}>Dada handsomeboy</p>
        </div>
    }
};
ReactDOM.render(<Dada />,document.body)

事件与状态关联

状态不仅仅实现了组件内部结果的清晰对应,还实现了组件与用户之间的交互,使用户与组件的行为紧紧结合起来

handleChange:function(e){
    this.setState({Dada:e.target.value});
}

this.setState设置状态

实例

var Dada =React.creatClass({
    getInitialState:function(){
        return{
            x:0,
            y:0
        }
    },
    handleMouseMove:function(e){
        this.setState({
            x:e.clientX,
            y:e.clientY
        });
    },
    render:function(){
        return <div onMouseMove={this.handleMouseMove} style={{  // 注意这里 onMouseMove
            width:'200px',
            height:'200px',
            backgroundColor:'#999'
        }}>
        {this.state.x+'.'+this.state.y}
        </div>
    }
});
ReactDOM.render(<Dada />,document.body)

React绑定事件和原生绑定事件的区别

react事件和原生事件的区别是:

  • react中的事件是绑定到document上面 , React并不会真正的绑定事件到每一个具体《》的元素上,而是采用事件代理的模式:
  • 而原生的事件是绑定到dom上面

相对绑定的地方来说,dom上的事件要优先于document上的事件执行,react的事件对象是合成。

参考链接:文章来源地址https://www.toymoban.com/news/detail-753412.html

  • https://blog.csdn.net/qq_40340943/article/details/107309779
  • https://www.bbsmax.com/A/Gkz1PBOgdR/

到了这里,关于react之事件处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++杂货铺】内管管理

    目录 🌈前言🌈 📁 C/C++中内存分布 📁 new 和 delete的使用 📁 new 和 delete的优点 📁 new 和 delete的原理  📂 operator new 和 operator delete函数  📂 内置类型  📂 自定义类型 📁 内存泄漏 📁 总结         欢迎收看本期【C++杂货铺】,本期内容讲解C++内存管理。包含了C++中内存

    2024年04月14日
    浏览(48)
  • 【Linux杂货铺】操作系统

    目录 🌈前言🌈 📁 冯诺依曼体系结构 📂 拓展问题:程序为什么要被加载到内存? 📂 主机与主机的交互 📁 操作系统的概念  📂 作用  📂 理解“管理”  📂 系统调用 和 库函数的概念 📁 总结         欢迎收看本期【Linux杂货铺】,本期内容将讲解计算机中操作系统

    2024年03月13日
    浏览(49)
  • 【C++杂货铺】详解string

    目录  🌈前言🌈 📁 为什么学习string 📁 认识string(了解) 📁 string的常用接口  📂 构造函数  📂 string类对象的容量操作  📂 string类对象的访问以及遍历操作​编辑  📂 string类对象的修改操作 📁 模拟实现string 📁 总结         欢迎观看本期【C++杂货铺】,本期内容

    2024年03月20日
    浏览(45)
  • 【C++杂货铺】拷贝构造函数

    📖 定义 拷贝构造函数 是构造函数的一个重载 ,它的本质还是 构造函数 ,那就意味着,只有在创建对象的时候,编译器才会自动调用它,那他和普通的构造函数有什么区别呢? 拷贝构造函数,是创建对象的时候,用一个已存在的对象,去初始化待创建的对象 。简单来说,

    2024年02月16日
    浏览(52)
  • 【C++杂货铺】详解list容器

    目录 🌈前言🌈 📁 介绍 📁 使用  📂 构造  📂 迭代器iterator  📂 capacity  📂 modifiers  📂 迭代器失效 📁 模拟实现  📂 迭代器的实现 📂 代码展示 📁 和vector的区别 📁 总结         欢迎收看本期【C++杂货铺】,本期内容将讲解STL中关于list的内容,会分为一下几个方

    2024年04月14日
    浏览(53)
  • 【C++杂货铺】运算符重载

    本文将以日期类为基础,去探寻运算符重载的特性与使用方法,下面先给出日期类的基础定义: 备注 :拷贝构造函数和析构函数,均可以不写,因为当前日期类的三个成员变量都是内置类型,没有动态申请空间,使用浅拷贝就可以。 📖 如何比较两个日期的大小? 现如今,

    2024年02月16日
    浏览(74)
  • 【C++杂货铺】缺省参数、函数重载

     缺省参数是 声明或定义函数时为函数的参数指定一个缺省值 。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。  上面代码在 fun 函数的形参部分给了缺省值10,这意味着在调用 fun 函数的时候可以传参,也可以不传参,如果传参了那形参

    2024年02月16日
    浏览(38)
  • 【Linux杂货铺】进程的基本概念

    目录 🌈前言🌈 📁进程的概念 📂描述进程-PCB 📂 查看进程 📂 查看正在运行的程序 📂杀死进程 📂通过系统调用获取进程标识符 📂通过系统调用创建进程 📂 进程的特点 📁进程的状态 📂 kill 信号 📂 僵尸进程  📂 孤儿进程 📂 运行状态 📂 阻塞状态 📂 挂起状态

    2024年03月19日
    浏览(42)
  • 【C++杂货铺】再谈类和对象

    在创建对象的时候,编译器通过调用构造函数,在构造函数体中,给对象中的各个成员变量一个合适的初值。 虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化, 构造函数体中的语句只能将其称为赋初值,而不能称作初

    2024年02月16日
    浏览(40)
  • 【C++杂货铺】string使用指南

    2024年02月14日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包