成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:說說對React事件機制的理解?

開發 前端
基于瀏覽器的事件機制自身實現了一套事件機制,包括事件注冊、事件的合成、事件冒泡、事件派發等。

[[408242]]

本文轉載自微信公眾號「JS每日一題」,作者灰灰。轉載本文請聯系JS每日一題公眾號。

一、是什么

React基于瀏覽器的事件機制自身實現了一套事件機制,包括事件注冊、事件的合成、事件冒泡、事件派發等

在React中這套事件機制被稱之為合成事件

合成事件(SyntheticEvent)

合成事件是 React模擬原生 DOM事件所有能力的一個事件對象,即瀏覽器原生事件的跨瀏覽器包裝器

根據 W3C規范來定義合成事件,兼容所有瀏覽器,擁有與瀏覽器原生事件相同的接口,例如:

  1. const button = <button onClick={handleClick}>按鈕</button> 

如果想要獲得原生DOM事件,可以通過e.nativeEvent屬性獲取

  1. const handleClick = (e) => console.log(e.nativeEvent);; 
  2. const button = <button onClick={handleClick}>按鈕</button> 

從上面可以看到React事件和原生事件也非常的相似,但也有一定的區別:

  • 事件名稱命名方式不同
  1. // 原生事件綁定方式 
  2. <button onclick="handleClick()">按鈕命名</button> 
  3.        
  4. // React 合成事件綁定方式 
  5. const button = <button onClick={handleClick}>按鈕命名</button> 
  • 事件處理函數書寫不同
  1. // 原生事件 事件處理函數寫法 
  2. <button onclick="handleClick()">按鈕命名</button> 
  3.        
  4. // React 合成事件 事件處理函數寫法 
  5. const button = <button onClick={handleClick}>按鈕命名</button> 

雖然onclick看似綁定到DOM元素上,但實際并不會把事件代理函數直接綁定到真實的節點上,而是把所有的事件綁定到結構的最外層,使用一個統一的事件去監聽

這個事件監聽器上維持了一個映射來保存所有組件內部的事件監聽和處理函數。當組件掛載或卸載時,只是在這個統一的事件監聽器上插入或刪除一些對象

當事件發生時,首先被這個統一的事件監聽器處理,然后在映射里找到真正的事件處理函數并調用。這樣做簡化了事件處理和回收機制,效率也有很大提升

二、執行順序

關于React合成事件與原生事件執行順序,可以看看下面一個例子:

  1. import  React  from 'react'
  2. class App extends React.Component{ 
  3.  
  4.   constructor(props) { 
  5.     super(props); 
  6.     this.parentRef = React.createRef(); 
  7.     this.childRef = React.createRef(); 
  8.   } 
  9.   componentDidMount() { 
  10.     console.log("React componentDidMount!"); 
  11.     this.parentRef.current?.addEventListener("click", () => { 
  12.       console.log("原生事件:父元素 DOM 事件監聽!"); 
  13.     }); 
  14.     this.childRef.current?.addEventListener("click", () => { 
  15.       console.log("原生事件:子元素 DOM 事件監聽!"); 
  16.     }); 
  17.     document.addEventListener("click", (e) => { 
  18.       console.log("原生事件:document DOM 事件監聽!"); 
  19.     }); 
  20.   } 
  21.   parentClickFun = () => { 
  22.     console.log("React 事件:父元素事件監聽!"); 
  23.   }; 
  24.   childClickFun = () => { 
  25.     console.log("React 事件:子元素事件監聽!"); 
  26.   }; 
  27.   render() { 
  28.     return ( 
  29.       <div ref={this.parentRef} onClick={this.parentClickFun}> 
  30.         <div ref={this.childRef} onClick={this.childClickFun}> 
  31.           分析事件執行順序 
  32.         </div> 
  33.       </div> 
  34.     ); 
  35.   } 
  36. export default App; 

輸出順序為:

  1. 原生事件:子元素 DOM 事件監聽!  
  2. 原生事件:父元素 DOM 事件監聽!  
  3. React 事件:子元素事件監聽!  
  4. React 事件:父元素事件監聽!  
  5. 原生事件:document DOM 事件監聽!  

可以得出以下結論:

  • React 所有事件都掛載在 document 對象上
  • 當真實 DOM 元素觸發事件,會冒泡到 document 對象后,再處理 React 事件
  • 所以會先執行原生事件,然后處理 React 事件
  • 最后真正執行 document 上掛載的事件

對應過程如圖所示:

所以想要阻止不同時間段的冒泡行為,對應使用不同的方法,對應如下:

  • 阻止合成事件間的冒泡,用e.stopPropagation()
  • 阻止合成事件與最外層 document 上的事件間的冒泡,用e.nativeEvent.stopImmediatePropagation()
  • 阻止合成事件與最外層document上的原生事件上的冒泡,通過判斷e.target來避免
  1. document.body.addEventListener('click', e => {    
  2.     if (e.target && e.target.matches('div.code')) {   
  3.         return;     
  4.     }     
  5.     this.setState({   active: false,    });   });  

三、總結

React事件機制總結如下:

  • React 上注冊的事件最終會綁定在document這個 DOM 上,而不是 React 組件對應的 DOM(減少內存開銷就是因為所有的事件都綁定在 document 上,其他節點沒有綁定事件)
  • React 自身實現了一套事件冒泡機制,所以這也就是為什么我們 event.stopPropagation()無效的原因。
  • React 通過隊列的形式,從觸發的組件向父組件回溯,然后調用他們 JSX 中定義的 callback
  • React 有一套自己的合成事件 SyntheticEvent

參考文獻

 

  • https://zh-hans.reactjs.org/docs/events.html
  • https://segmentfault.com/a/1190000015725214?utm_source=sf-similar-article
  • https://segmentfault.com/a/1190000038251163

 

責任編輯:武曉燕 來源: JS每日一題
相關推薦

2021-06-10 07:51:07

Node.js循環機制

2021-07-07 08:36:45

React應用場景

2021-07-13 07:52:03

ReactHooks組件

2021-05-31 10:35:34

TCPWebSocket協議

2021-07-29 07:55:20

React Fiber架構引擎

2021-07-12 08:35:24

組件應用場景

2021-06-29 09:47:34

ReactSetState機制

2021-06-07 09:41:48

NodeBuffer 網絡協議

2021-06-08 08:33:23

NodeStream數據

2021-09-13 09:23:52

TypeScript命名空間

2021-06-03 08:14:01

NodeProcessJavaScript

2021-10-29 09:40:21

設計模式軟件

2021-07-08 06:51:29

React函數組件

2021-06-04 07:55:30

Node Fs 操作

2019-05-10 10:50:04

Spring AOPJDK動態代理CGLIB動態代理

2020-08-03 07:38:12

單例模式

2021-11-25 10:18:42

RESTfulJava互聯網

2021-08-09 07:47:40

Git面試版本

2021-06-15 10:01:02

應用系統軟件

2021-07-19 07:55:24

Redux中間件原理
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美在线一区二区三区 | 国产精品免费一区二区 | 超碰成人在线观看 | 一区二区三区久久 | 美女天天操| 亚洲国产精品人人爽夜夜爽 | 久久免费小视频 | 欧美一区2区三区4区公司 | 久久久久91| 日本免费一区二区三区四区 | 777zyz色资源站在线观看 | 91av在线免费看 | 欧美一区二区三区四区在线 | 欧美精品久久久久 | 精品视频在线观看 | 亚洲网一区 | 天堂精品视频 | 午夜三级网站 | 天天综合国产 | 日本一区二区高清不卡 | 中文在线亚洲 | 成人免费一区二区三区牛牛 | 国产精品久久久久久久免费大片 | 韩国av影院 | 国内精品久久久久久影视8 最新黄色在线观看 | 日韩成人在线播放 | 亚洲午夜在线 | 精品视频一二区 | 中国一级特黄真人毛片免费观看 | 国产精品美女久久久久aⅴ国产馆 | 成人小视频在线观看 | 欧美一区不卡 | 国产一区二区三区高清 | 成人精品一区 | 亚洲成人综合在线 | 国产 日韩 欧美 在线 | 免费成人高清在线视频 | 成人精品一区二区三区四区 | www.99精品| 免费一区 | 国产高清在线观看 |