资讯专栏INFORMATION COLUMN

浅谈React事件机制

moven_j / 1810人阅读

摘要:事件简介事件是合成事件,所有事件都自动绑定到最外层上。支持事件的冒泡机制,我们可以使用和来中断它。这样做简化了事件处理和回收机制,效率也有很大提升。事件类型合成事件的事件类型是原生事件类型的一个子集。

React事件简介

React事件是合成事件,所有事件都自动绑定到最外层上。因为Virtual DOM 在内存中是以对象的形式存在的,所以React 基于 Virtual DOM 实现了一个 SyntheticEvent (合成事件)层,我们所定义的事件 处理器会接收到一个 SyntheticEvent 对象的实例。支持事件的冒泡机制,我 们可以使用 stopPropagation() 和 preventDefault() 来中断它。没有兼容问题。

事件绑定?

事件绑定的方式与原生事件绑定相似,但是必须使用驼峰的形式来书写事件的属性名(比如 onClick);
React 并不会像 DOM0 级事件那样将事件处理器直接绑定到 HTML 元素之上,而是一个函数指针:

button onclick="handleClick()">Test //dom0
合成事件的实现机制

在 React 底层,主要对合成事件做了两件事:事件委派和自动绑定

1.事件委派

React并不会把事件处理函数直接绑定到真实的节点上,而是把所有事件绑定到结构的最外层,使用一个统一的事件监听器,这个事件监听器上维持了一个映射来保存所有组件内部的事件监听和处理函数。当组件挂载或卸载时,只是 在这个统一的事件监听器上插入或删除一些对象;当事件发生时,首先被这个统一的事件监听器 处理,然后在映射里找到真正的事件处理函数并调用。这样做简化了事件处理和回收机制,效率 也有很大提升。

2. 自动绑定

在 React 组件中,每个方法的上下文都会指向该组件的实例,即自动绑定this为当前组件。但是使用 ES6 classes 或者纯函数时,需要手动实现this的绑定。具体有如下方法:

1》通过bind方法实现;每次重新渲染时,都会生成一个新的函数实例保存在listenerBank中,浪费内存

render() {
    // 通过bind方法实现,可以传递参数
    return ;
}
render() {//不传递参数时,也可以使用::代替
    return ;
}

2》构造器内使用bind绑定;不用每次调用都绑定。推荐

    import React, { Component } from "react";
    class App extends Component { constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this); }
        handleClick(e) { console.log(e);
    }
    render() {
        return ;
    } }

3》箭头函数

class App extends Component { //不能带参数
    const handleClick = (e) => {
       console.log(e);
    };
    render() {
        return ;
    } 
}
class App extends Component { //也是每次渲染都会生成新的函数实例
    handleClick(e) {
        console.log(e); 
    }
  render() {
    return  
    }
}
对比React合成事件与JavaScript原生事件

对于无法使用 React 合成事件的场景,我们还需要使用原生事件来完成。从 4 个方面来对比 React 合成事件与 JavaScript 原生事件。
1.事件传播与阻止事件传播
浏览器原生 DOM 事件的传播可以分为 3 个阶段:事件捕获阶段目标对象本身的事件处理程序调用以及事件冒泡。将 e.addEventListener() 的第三 个参数设置为 true 时,可以为事件注册捕获阶段,但是ie9一下不支持,所以没什么意义。react只提供了事件冒泡机制,通过e.prevent- Default() 即可。阻止原生事件传播需要使用 e.preventDefault(),不过对于不支持该方法的浏览器(IE9 以 下),只能使用 e.cancelBubble = true 来阻止。
2.事件类型
React 合成事件的事件类型是 JavaScript 原生事件类型的一个子集。
3.事件绑定方式
受到 DOM 标准的影响,绑定浏览器原生事件的方式也有很多种,具体如下所示。
1》直接在 DOM 元素中绑定:


2》在 JavaScript 中,通过为元素的事件属性赋值的方式实现绑定:

el.onclick = e => { console.log(e); }

3》通过事件监听函数来实现绑定:

el.addEventListener("click", () => {}, false);
el.attachEvent("onclick", () => {});

相比而言,React 合成事件的绑定方式则简单得多:



4.事件对象
原生 DOM 事件对象在 W3C 标准和 IE 标准下存在着差异。在低版本的 IE 浏览器中,只能
使用 window.event 来获取事件对象。而在 React 合成事件系统中,不存在这种兼容性问题,在事
件处理函数中可以得到一个合成事件对象。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/54163.html

相关文章

  • 浅谈React事件机制

    摘要:事件简介事件是合成事件,所有事件都自动绑定到最外层上。支持事件的冒泡机制,我们可以使用和来中断它。这样做简化了事件处理和回收机制,效率也有很大提升。事件类型合成事件的事件类型是原生事件类型的一个子集。 React事件简介 React事件是合成事件,所有事件都自动绑定到最外层上。因为Virtual DOM 在内存中是以对象的形式存在的,所以React 基于 Virtual DOM 实现了...

    MyFaith 评论0 收藏0
  • 浅谈React Fiber

    摘要:因为版本将真正废弃这三生命周期到目前为止,的渲染机制遵循同步渲染首次渲染,更新时更新时卸载时期间每个周期函数各司其职,输入输出都是可预测,一路下来很顺畅。通过进一步观察可以发现,预废弃的三个生命周期函数都发生在虚拟的构建期间,也就是之前。 showImg(https://segmentfault.com/img/bVbweoj?w=559&h=300); 背景 前段时间准备前端招聘事项...

    izhuhaodev 评论0 收藏0
  • 2018 浅谈前端面试那些事

    摘要:声明的变量不得改变值,这意味着,一旦声明变量,就必须立即初始化,不能留到以后赋值。 虽然今年没有换工作的打算 但为了跟上时代的脚步 还是忍不住整理了一份最新前端知识点 知识点汇总 1.HTML HTML5新特性,语义化浏览器的标准模式和怪异模式xhtml和html的区别使用data-的好处meta标签canvasHTML废弃的标签IE6 bug,和一些定位写法css js放置位置和原因...

    LiuRhoRamen 评论0 收藏0
  • 2018 浅谈前端面试那些事

    摘要:声明的变量不得改变值,这意味着,一旦声明变量,就必须立即初始化,不能留到以后赋值。 虽然今年没有换工作的打算 但为了跟上时代的脚步 还是忍不住整理了一份最新前端知识点 知识点汇总 1.HTML HTML5新特性,语义化浏览器的标准模式和怪异模式xhtml和html的区别使用data-的好处meta标签canvasHTML废弃的标签IE6 bug,和一些定位写法css js放置位置和原因...

    stormgens 评论0 收藏0
  • 2018 浅谈前端面试那些事

    摘要:声明的变量不得改变值,这意味着,一旦声明变量,就必须立即初始化,不能留到以后赋值。 虽然今年没有换工作的打算 但为了跟上时代的脚步 还是忍不住整理了一份最新前端知识点 知识点汇总 1.HTML HTML5新特性,语义化浏览器的标准模式和怪异模式xhtml和html的区别使用data-的好处meta标签canvasHTML废弃的标签IE6 bug,和一些定位写法css js放置位置和原因...

    Hujiawei 评论0 收藏0

发表评论

0条评论

moven_j

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<