MST

星途 面试题库

面试题:React中合成事件与原生事件的区别

请阐述React中合成事件与原生JavaScript事件在使用和机制上有哪些主要区别,结合合成事件系统的工作原理说明。
12.5万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

使用区别

  1. 绑定方式

    • 原生JavaScript事件:通过addEventListener方法直接在DOM元素上绑定事件。例如:
    const button = document.getElementById('myButton');
    button.addEventListener('click', function () {
        console.log('原生事件被触发');
    });
    
    • React合成事件:采用驼峰命名法在JSX中绑定事件。例如:
    import React, { Component } from'react';
    class MyButton extends Component {
        handleClick = () => {
            console.log('合成事件被触发');
        }
        render() {
            return <button onClick={this.handleClick}>点击我</button>;
        }
    }
    
  2. 事件对象

    • 原生JavaScript事件:事件对象是浏览器原生的,不同浏览器可能存在兼容性问题。例如,获取事件目标在IE8及以前版本需要使用event.srcElement,而现代浏览器使用event.target
    • React合成事件:React将不同浏览器的原生事件进行了封装,提供了统一的合成事件对象,具有更好的跨浏览器兼容性。例如,无论在何种浏览器环境下,都可以通过event.target获取事件目标。
  3. 事件冒泡和捕获

    • 原生JavaScript事件:可以通过addEventListener的第三个参数(useCapture)来控制事件是在捕获阶段还是冒泡阶段触发。例如:
    const div = document.getElementById('myDiv');
    div.addEventListener('click', function () {
        console.log('冒泡阶段触发');
    }, false);
    div.addEventListener('click', function () {
        console.log('捕获阶段触发');
    }, true);
    
    • React合成事件:默认使用冒泡机制,并且React对事件冒泡做了特殊处理,在组件树中按照从子组件到父组件的顺序触发。如果想要阻止事件传播,可以调用event.stopPropagation()方法。例如:
    import React, { Component } from'react';
    class Child extends Component {
        handleClick = (event) => {
            event.stopPropagation();
            console.log('子组件点击,阻止冒泡');
        }
        render() {
            return <button onClick={this.handleClick}>子按钮</button>;
        }
    }
    class Parent extends Component {
        handleClick = () => {
            console.log('父组件点击');
        }
        render() {
            return (
                <div onClick={this.handleClick}>
                    <Child />
                </div>
            );
        }
    }
    

机制区别

  1. 事件委托
    • 原生JavaScript事件:需要手动实现事件委托,例如要监听多个子元素的点击事件,可以将点击事件绑定到父元素上,通过判断event.target来确定具体触发事件的子元素。
    const parent = document.getElementById('parent');
    parent.addEventListener('click', function (event) {
        if (event.target.tagName === 'LI') {
            console.log('点击了列表项');
        }
    });
    
    • React合成事件:采用事件委托机制,将所有事件绑定到最外层的DOM元素(通常是document)上。当事件发生时,React会根据事件的类型和目标元素,在组件树中找到对应的组件实例,并调用相应的事件处理函数。这样可以减少内存开销,提高性能。
  2. 工作原理
    • React合成事件系统
      • 事件注册:在组件挂载时,React会将所有支持的事件(如clickchange等)绑定到最外层的DOM元素上。这些事件处理函数是统一的分发函数。
      • 事件触发:当某个DOM元素上的事件发生时,会先触发最外层DOM元素上的统一分发函数。
      • 事件匹配和处理:分发函数会根据事件类型和目标元素,在组件树中找到对应的组件实例,并根据组件的事件绑定情况,找到要执行的具体事件处理函数。然后,React会创建一个合成事件对象,这个对象封装了原生事件对象,并提供了统一的接口。最后,调用对应的事件处理函数,并将合成事件对象作为参数传递进去。
      • 事件回收:事件处理函数执行完毕后,React会回收合成事件对象,以便下次复用,从而减少内存开销。