溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

react的合成事件是什么

發(fā)布時(shí)間:2022-12-16 09:36:12 來(lái)源:億速云 閱讀:170 作者:iii 欄目:web開(kāi)發(fā)

本篇內(nèi)容介紹了“react的合成事件是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

React合成事件是React模擬原生DOM事件所有能力的一個(gè)事件對(duì)象,即瀏覽器原生事件的跨瀏覽器包裝器;它根據(jù)W3C規(guī)范來(lái)定義合成事件,兼容所有瀏覽器,擁有與瀏覽器原生事件相同的接口。在React中,所有事件都是合成的,不是原生DOM事件,但可以通過(guò)“e.nativeEvent”屬性獲取DOM事件。

一、合成事件是什么

React基于瀏覽器的事件機(jī)制自身實(shí)現(xiàn)了一套事件機(jī)制,包括事件注冊(cè)、事件的合成、事件冒泡、事件派發(fā)等

在React中這套事件機(jī)制被稱之為合成事件

合成事件(SyntheticEvent)

React 合成事件(SyntheticEvent)是 React 模擬原生 DOM 事件所有能力的一個(gè)事件對(duì)象,即瀏覽器原生事件的跨瀏覽器包裝器。它根據(jù) W3C 規(guī)范 來(lái)定義合成事件,兼容所有瀏覽器,擁有與瀏覽器原生事件相同的接口。例如

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

在 React 中,所有事件都是合成的,不是原生 DOM 事件,但可以通過(guò) e.nativeEvent 屬性獲取 DOM 事件。 比如:

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

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

  • 事件名稱命名方式不同

// 原生事件綁定方式
<button onclick="handleClick()">按鈕命名</button>
      
// React 合成事件綁定方式
const button = <button onClick={handleClick}>按鈕命名</button>

  • 事件處理函數(shù)書(shū)寫(xiě)不同

// 原生事件 事件處理函數(shù)寫(xiě)法
<button onclick="handleClick()">按鈕命名</button>
      
// React 合成事件 事件處理函數(shù)寫(xiě)法
const button = <button onClick={handleClick}>按鈕命名</button>

雖然onclick看似綁定到DOM元素上,但實(shí)際并不會(huì)把事件代理函數(shù)直接綁定到真實(shí)的節(jié)點(diǎn)上,而是把所有的事件綁定到結(jié)構(gòu)的最外層,使用一個(gè)統(tǒng)一的事件去監(jiān)聽(tīng)。

這個(gè)事件監(jiān)聽(tīng)器上維持了一個(gè)映射來(lái)保存所有組件內(nèi)部的事件監(jiān)聽(tīng)和處理函數(shù)。當(dāng)組件掛載或卸載時(shí),只是在這個(gè)統(tǒng)一的事件監(jiān)聽(tīng)器上插入或刪除一些對(duì)象。

當(dāng)事件發(fā)生時(shí),首先被這個(gè)統(tǒng)一的事件監(jiān)聽(tīng)器處理,然后在映射里找到真正的事件處理函數(shù)并調(diào)用。這樣做簡(jiǎn)化了事件處理和回收機(jī)制,效率也有很大提升。

二、執(zhí)行順序

關(guān)于React合成事件與原生事件執(zhí)行順序,可以看看下面一個(gè)例子:

import  React  from 'react';
class App extends React.Component{

  constructor(props) {
    super(props);
    this.parentRef = React.createRef();
    this.childRef = React.createRef();
  }
  componentDidMount() {
    console.log("React componentDidMount!");
    this.parentRef.current?.addEventListener("click", () => {
      console.log("原生事件:父元素 DOM 事件監(jiān)聽(tīng)!");
    });
    this.childRef.current?.addEventListener("click", () => {
      console.log("原生事件:子元素 DOM 事件監(jiān)聽(tīng)!");
    });
    document.addEventListener("click", (e) => {
      console.log("原生事件:document DOM 事件監(jiān)聽(tīng)!");
    });
  }
  parentClickFun = () => {
    console.log("React 事件:父元素事件監(jiān)聽(tīng)!");
  };
  childClickFun = () => {
    console.log("React 事件:子元素事件監(jiān)聽(tīng)!");
  };
  render() {
    return (
      <div ref={this.parentRef} onClick={this.parentClickFun}>
        <div ref={this.childRef} onClick={this.childClickFun}>
          分析事件執(zhí)行順序
        </div>
      </div>
    );
  }
}
export default App;

輸出順序?yàn)椋?/p>

原生事件:子元素 DOM 事件監(jiān)聽(tīng)! 
原生事件:父元素 DOM 事件監(jiān)聽(tīng)! 
React 事件:子元素事件監(jiān)聽(tīng)! 
React 事件:父元素事件監(jiān)聽(tīng)! 
原生事件:document DOM 事件監(jiān)聽(tīng)!

可以得出以下結(jié)論:

  • React 所有事件都掛載在 document 對(duì)象上

  • 當(dāng)真實(shí) DOM 元素觸發(fā)事件,會(huì)冒泡到 document 對(duì)象后,再處理 React 事件

  • 所以會(huì)先執(zhí)行原生事件,然后處理 React 事件

  • 最后真正執(zhí)行 document 上掛載的事件

對(duì)應(yīng)過(guò)程如圖所示:

react的合成事件是什么

所以想要阻止不同時(shí)間段的冒泡行為,對(duì)應(yīng)使用不同的方法,對(duì)應(yīng)如下:

  • 阻止合成事件間的冒泡,用e.stopPropagation()

  • 阻止合成事件與最外層 document 上的事件間的冒泡,用e.nativeEvent.stopImmediatePropagation()

  • 阻止合成事件與除最外層document上的原生事件上的冒泡,通過(guò)判斷e.target來(lái)避免

document.body.addEventListener('click', e => {   
    if (e.target && e.target.matches('div.code')) {  
        return;    
    }    
    this.setState({   active: false,    });   });

“react的合成事件是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI