【React】合成事件语法

React 合成事件是 React 为了处理浏览器之间的事件差异而提供的一种跨浏览器的事件系统。它封装了原生的 DOM 事件,提供了一致的事件处理机制。

合成事件与原生事件的区别:

  • 合成事件是 React 自己实现的,封装了原生事件。
  • 合成事件依然可以通过 event.nativeEvent 访问原生事件。
  • 合成事件支持事件池化,事件处理函数执行完后会被回收。

获取原生事件的方法:

1、合成事件绑定一个"普通函数"

打印出thisundefined,该普通函数相当于是挂载在当前实例对象的原型上,即:
Demo.prototype => Demo.prototype.handle = function handle(){ }

React 会通过 onClick={this.handle1} 传递事件处理函数,但它并没有自动绑定 this,导致 this 在方法执行时是 undefined,而不是组件实例

javascript 复制代码
class Demo extends React.Component {

    handle1() { 
        console.log(this); //undefined
    }

    render() {
        return <div>
            <button onClick={this.handle1}>按钮1</button>
        </div>;
    }
}

2、给调用的函数绑定this

在调用handle2时,绑定this,即:this.handle2.bind(this, 10, 20),后面是传递的参数。

bind在React事件绑定的中运用

  • 绑定的方法是一个普通函数,需要改变函数中的this是实例,此时需要用到bind「一般都是绑定箭头函数」
  • 想给函数传递指定的实参,可以基于bind预先处理「bind会把合成事件对象以最后一个实参传递给函数
javascript 复制代码
class Demo extends React.Component {
  
    handle2(x, y, ev) {
        // 只要方法经过bind处理了,那么最后一个实参,就是传递的合成事件对象!!
        console.log(this, x, y, ev); //实例 10 20 合成事件对象
    }

    render() {
        return <div>
            <button onClick={this.handle2.bind(this, 10, 20)}>按钮2</button>
        </div>;
    }
}

打印的this为组件的实例对象。

打印的ev是传递的合成事件对象
合成事件对象SyntheticBaseEvent:在React合成事件触发的时候,也可以获取到事件对象,只不过此对象是合成事件对象「React内部经过特殊处理,把各个浏览器的事件对象统一化后,构建的一个事件对象」。合成事件对象中,也包含了浏览器内置事件对象中的一些属性和方法「常用的基本都有」

  • clientX/clientY
  • pageX/pageY
  • target
  • type
  • preventDefault
  • stopPropagation
  • nativeEvent:基于这个属性,可以获取浏览器内置『原生』的事件对象

3、设置普通函数为箭头函数

把绑定的函数设置为"箭头函数",让其使用上下文中的this「也就是组件实例」。

javascript 复制代码
class Demo extends React.Component {
    handle3 = (ev) => {  //实例.handle3=()=>{....}
        console.log(this); //实例
        console.log(ev); //SyntheticBaseEvent 合成事件对象「React内部经过特殊处理,把各个浏览器的事件对象统一化后,构建的一个事件对象」
    };
    render() {
        return <div>
            <button onClick={this.handle3}>按钮3</button>
        </div>;
    }
}

4、设置普通函数为箭头函数并在调用时进行额外参数

因为设置了普通函数为箭头函数,所以进行bind绑定this的时候,对于绑定的谁,其实不重要了,因为设置了普通函数为箭头函数,此时在函数中this就指向了组件实例。

javascript 复制代码
class Demo extends React.Component {
    
    handle4 = (x, ev) => {
        console.log(x, ev); //10 合成事件对象
    };

    render() {
        return <div>
            <button onClick={this.handle4.bind(null, 10)}>按钮4</button>
        </div>;
    }
}

源码

javascript 复制代码
class Demo extends React.Component {
    /* 
    基于React内部的处理,如果我们给合成事件绑定一个"普通函数",当事件行为触发,绑定的函数执行;方法中的this会是undefined「不好」!! 解决方案:this->实例
      + 我们可以基于JS中的bind方法:预先处理函数中的this和实参的
      + 推荐:当然也可以把绑定的函数设置为"箭头函数",让其使用上下文中的this「也就是我们的实例」

    合成事件对象SyntheticBaseEvent:我们在React合成事件触发的时候,也可以获取到事件对象,只不过此对象是合成事件对象「React内部经过特殊处理,把各个浏览器的事件对象统一化后,构建的一个事件对象」
      合成事件对象中,也包含了浏览器内置事件对象中的一些属性和方法「常用的基本都有」
      + clientX/clientY
      + pageX/pageY
      + target
      + type
      + preventDefault
      + stopPropagation
      + ...
      + nativeEvent:基于这个属性,可以获取浏览器内置『原生』的事件对象
      + ...
    */
     
    handle1() { //Demo.prototype => Demo.prototype.handle=function handle(){}
        console.log(this); //undefined
    }
    handle2(x, y, ev) {
        // 只要方法经过bind处理了,那么最后一个实参,就是传递的合成事件对象!!
        console.log(this, x, y, ev); //实例 10 20 合成事件对象
    }
    handle3 = (ev) => {  //实例.handle3=()=>{....}
        console.log(this); //实例
        console.log(ev); //SyntheticBaseEvent 合成事件对象「React内部经过特殊处理,把各个浏览器的事件对象统一化后,构建的一个事件对象」
    };
    handle4 = (x, ev) => {
        console.log(x, ev); //10 合成事件对象
    };

    render() {
        /*
         bind在React事件绑定的中运用
           + 绑定的方法是一个普通函数,需要改变函数中的this是实例,此时需要用到bind「一般都是绑定箭头函数」
           + 想给函数传递指定的实参,可以基于bind预先处理「bind会把事件对象以最后一个实参传递给函数」 
         */
        return <div>
            <button onClick={this.handle1}>按钮1</button>
            <button onClick={this.handle2.bind(this, 10, 20)}>按钮2</button>
            <button onClick={this.handle3}>按钮3</button>
            <button onClick={this.handle4.bind(null, 10)}>按钮4</button>
        </div>;
    }
}
相关推荐
Zuckjet_2 小时前
开启 3D 之旅 - 你的第一个 WebGL 三角形
前端·javascript·3d·webgl
2401_863801462 小时前
探索 12 种 3D 文件格式:综合指南
前端·3d
珍宝商店3 小时前
前端老旧项目全面性能优化指南与面试攻略
前端·面试·性能优化
bitbitDown3 小时前
四年前端分享给你的高效开发工具库
前端·javascript·vue.js
YAY_tyy3 小时前
【JavaScript 性能优化实战】第六篇:性能监控与自动化优化
javascript·性能优化·自动化
gnip4 小时前
实现AI对话光标跟随效果
前端·javascript
脑花儿5 小时前
ABAP SMW0下载Excel模板并填充&&剪切板方式粘贴
java·前端·数据库
闭着眼睛学算法6 小时前
【华为OD机考正在更新】2025年双机位A卷真题【完全原创题解 | 详细考点分类 | 不断更新题目 | 六种主流语言Py+Java+Cpp+C+Js+Go】
java·c语言·javascript·c++·python·算法·华为od
烛阴6 小时前
【TS 设计模式完全指南】构建你的专属“通知中心”:深入观察者模式
javascript·设计模式·typescript
lumi.6 小时前
Vue.js 从入门到实践1:环境搭建、数据绑定与条件渲染
前端·javascript·vue.js