自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

React 合成事件和 JavaScript 事件有什么區(qū)別?

開發(fā) 前端
五一前幫一個同學做模擬面試的時候,聊到了 React 的合成事件和 JavaScript 原生事件的差異性問題。我發(fā)現(xiàn)很多 React 技術(shù)棧的同學對這一方面好像理解的并不清楚,所以今天咱們這篇文章主要就來說下這個問題。

五一前幫一個同學做模擬面試的時候,聊到了 React 的合成事件和 JavaScript 原生事件的差異性問題。我發(fā)現(xiàn)很多 React 技術(shù)棧的同學對這一方面好像理解的并不清楚,所以今天咱們這篇文章主要就來說下這個問題。

1.設(shè)計理念

React合成事件 封裝 了原生瀏覽器事件,提供了統(tǒng)一的API接口,使得開發(fā)者無論瀏覽器環(huán)境如何都可以用相同的方式處理事件。這種方法的主要目的是:確??鐬g覽器的一致性并與 React 的聲明式編程模型和生命周期集成。

JavaScript 中的事件處理程序 由瀏覽器直接提供,與特定的瀏覽器行為密切相關(guān)。不同的瀏覽器可能有不同的實現(xiàn)和支持級別。

2.瀏覽器兼容性

React 合成事件處理所有瀏覽器兼容性問題,為開發(fā)人員提供一個干凈、一致的事件處理接口。

例如:它標準化了不同瀏覽器之間的事件行為,以事件冒泡和默認行為為例,咱們來看下它的實現(xiàn):

// 構(gòu)造器定義,接收事件配置、目標實例、本地事件和事件目標作為參數(shù)
function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
  this.dispatchConfig = dispatchConfig; // 存儲事件的配置信息,例如事件類型
  this._targetInst = targetInst; //存儲觸發(fā)事件的組件實例
  this.nativeEvent = nativeEvent; // 存儲本機瀏覽器事件對象
  this.target = nativeEventTarget; // 存儲事件的原生目標,即事件最初發(fā)生的多姆元素
  this.currentTarget = null; // 處理事件的當前多姆元素將在事件處理期間設(shè)置
}

// SyneticEvents的原型對象,定義所有實例共享的方法
SyntheticEvent.prototype = {
  // Method to prevent the default event behavior
  preventDefault: function() {
    this.defaultPrevented = true; // 標志著事件的默認行為已被阻止
    const event = this.nativeEvent; // 獲取本地事件對象
    if (!event) {
      return; // 如果沒有本地事件對象,則直接返回
    }

    // 如果本機事件對象支持preventAlert方法,請調(diào)用它以防止默認行為
    if (event.preventDefault) {
      event.preventDefault();
    } else if (typeof event.returnValue !== 'undefined') { // 與IE8及以下版本兼容
      event.returnValue = false; // 在較舊的IE瀏覽器中,使用returnValue= true來防止默認行為
    }
  },
  
  // 阻止事件進一步傳播的方法
  stopPropagation: function() {
    const event = this.nativeEvent; // 獲取本地事件對象
    if (!event) {
      return; // 如果沒有本地事件對象,則直接返回
    }

    // 如果本機事件對象支持stopPropagation方法,請調(diào)用它來停止事件冒泡
    if (event.stopPropagation) {
      event.stopPropagation();
    } else if (typeof event.cancelBubble !== 'undefined') { // 與IE8及以下版本兼容
      event.cancelBubble = true; // 在較舊的IE瀏覽器中,使用cancelBubble=true來停止事件冒泡
    }
  },
  // ...
};

3.性能優(yōu)化

React 合成事件使用 事件池 來提高性能,即:重(chong)用事件對象。

這意味著:事件回調(diào)函數(shù)執(zhí)行后,事件對象的所有屬性都會被清除并回收以供重用,減少垃圾收集和內(nèi)存使用的壓力。

// 事件對象重用和回收的核心邏輯
SyntheticEvent.prototype.destructor = function() {
  this.target = null;
  this.currentTarget = null;
  this.dispatchConfig = null;
  this._targetInst = null;
  this.nativeEvent = null;
  this.isDefaultPrevented = false;
  this.isPropagationStopped = false;
  // 清除所有屬性....
};

// Event pool
var eventPool = [];

// 從池中檢索事件對象的函數(shù)
SyntheticEvent.getPooled = function(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
  if (eventPool.length) {
    var instance = eventPool.pop();
    SyntheticEvent.call(instance, dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
    return instance;
  }
  return new SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
};

// 將事件對象返回到池的函數(shù)
SyntheticEvent.release = function(event) {
  event.destructor();
  eventPool.push(event);
};

而 JavaScript 事件每次觸發(fā)時都會創(chuàng)建一個新的事件對象,這可能會增加內(nèi)存使用量和垃圾收集的頻率,特別是當事件頻繁觸發(fā)時(例如:滾動 或 輸入)?!?/p>

4.使用模式

React 通過 JSX語法 允許我們直接在組件的元素上聲明事件處理函數(shù)(合成事件)。

React 會自動處理添加和刪除事件監(jiān)聽器,確保組件安裝時添加監(jiān)聽器,卸載時刪除監(jiān)聽器,從而避免內(nèi)存泄漏。

export default function Button() {
  function handleClick() {
    console.log('click!');
  }

  return <button onClick={handleClick}>點我</button>;
}

Javascript 事件需要手動調(diào)用 addEventListener 添加事件監(jiān)聽器,同樣手動調(diào)用removeEventListener 刪除事件監(jiān)聽器:

document.addEventListener('DOMContentLoaded', function() {
  const button = document.querySelector('button');

  button.addEventListener('click', function() {
    console.log('click');
  });
});

5.總結(jié)

所以,React 的合成事件是 React 提供了一種高度抽象和集成的事件處理方式,并且可以更好地處理瀏覽器兼容性以及優(yōu)化(卸載事件)等問題。它最終依然會被解析成原生事件。

而 JavaScript 原生事件就是瀏覽器所提供的標準 API,使用時需要更多的處理兼容性以及性能等邊緣邏輯。

責任編輯:華軒 來源: 程序員Sunday
相關(guān)推薦

2020-08-02 23:20:36

JavaScriptmap()forEach()

2024-05-27 00:40:00

2024-09-09 13:10:14

2021-12-17 14:40:02

while(1)for(;;)語言

2022-02-27 15:33:22

安全CASBSASE

2022-08-02 08:23:37

SessionCookies

2024-03-05 18:59:59

前端開發(fā)localhost

2021-05-16 14:26:08

RPAIPACIO

2020-03-09 20:56:19

LoRaLoRaWAN無線技術(shù)

2022-09-07 18:32:57

并發(fā)編程線程

2022-06-06 14:53:02

LoRaLoRaWAN

2022-09-08 18:38:26

LinuxWindowsmacOS

2020-11-09 14:07:53

PyQtQt編程

2023-12-25 15:40:55

React開發(fā)

2021-07-01 07:51:45

React事件綁定

2023-12-15 09:21:17

ObjectJavaString

2022-08-22 07:06:32

MyBatisSQL占位符

2022-08-31 08:33:54

Bash操作系統(tǒng)Linux

2025-03-10 09:30:00

SpringJava開發(fā)

2020-11-14 15:38:38

JavaScript代碼技術(shù)
點贊
收藏

51CTO技術(shù)棧公眾號