国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

React事件機制

lavnFan / 3216人閱讀

摘要:注冊事件的回調函數由來統一管理,根據事件的類型和組件標識為唯一標識事件并進行存儲。利用中注入的例如會將原生的事件轉化成合成的事件,然后批量執行存儲的回調函,回調函數的執行分為兩步,第一步是將所有的合成事件放到事件隊列里面,第二步是逐個執行。

  最近在閱讀《深入React技術棧》一書中,發現了之前使用React中并沒有注意到的React事件與瀏覽器原生事件之間的區別,鑒于好久已經沒有寫東西了,就想寫一下關于React事件的文章。
  首先我們舉個例子,如果我們需要實現一個組件,這個組件點擊按鈕會顯示一個二維碼,點擊二維碼之外的區域可以隱藏二維碼,但是點擊二維碼本身卻不會關閉,代碼如下:

//代碼來源于《深入React技術棧》2.1.4節
class QrCode extends Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
    this.handleClickQr = this.handleClickQr.bind(this);
    this.state = {
      active: false,
    };
  }
  
  componentDidMount() {
    document.body.addEventListener("click", e => {
      this.setState({
        active: false,
      });
    });
  }

  componentWillUnmount() {
    document.body.removeEventListener("click");
  }
  
  handleClick() {
    this.setState({
      active: !this.state.active,
    });
  }
  
  handleClickQr(e) {
    e.stopPropagation();
  }

  render() {
    return (
      
); } }

  上面代碼從感官上感覺確實可以實現要求的組件,但事實上我們運行上述代碼可以發現,點擊二維碼本身也會導致二維碼的隱藏,現在就有意思了,我們來仔細分析一下。
  其實React事件并沒有原生的綁定在真實的DOM上,而是使用了行為委托方式實現事件機制。
  

  如上圖所示,在JavaScript中,事件的觸發實質上是要經過三個階段:事件捕獲、目標對象本身的事件處理和事件冒泡,假設在div中觸發了click事件,實際上首先經歷捕獲階段會由父級元素將事件一直傳遞到事件發生的元素,執行完目標事件本身的處理事件后,然后經歷冒泡階段,將事件從子元素向父元素冒泡。正因為事件在DOM的傳遞經歷這樣一個過程,從而為行為委托提供了可能。通俗地講,行為委托的實質就是將子元素事件的處理委托給父級元素處理。React會將所有的事件都綁定在最外層(document),使用統一的事件監聽,并在冒泡階段處理事件,當掛載或者卸載組件時,只需要在通過的在統一的事件監聽位置增加或者刪除對象,因此可以提高效率。
  并且React并沒有使用原生的瀏覽器事件,而是在基于Virtual DOM的基礎上實現了合成事件(SyntheticEvent),事件處理程序接收到的是SyntheticEvent的實例。SyntheticEvent完全符合W3C的標準,因此在事件層次上具有瀏覽器兼容性,與原生的瀏覽器事件一樣擁有同樣的接口,可以通過stopPropagation()preventDefault()相應的中斷。如果需要訪問當原生的事件對象,可以通過引用nativeEvent獲得。
  
  上圖為大致的React事件機制的流程圖,React中的事件機制分為兩個階段:事件注冊和事件觸發:

事件注冊  
  React在組件加載(mount)和更新(update)時,其中的ReactDOMComponent會對傳入的事件屬性進行處理,對相關事件進行注冊和存儲。document中注冊的事件不處理具體的事件,僅對事件進行分發。ReactBrowserEventEmitter作為事件注冊入口,擔負著事件注冊和事件觸發。注冊事件的回調函數由EventPluginHub來統一管理,根據事件的類型(type)和組件標識(_rootNodeID)為key唯一標識事件并進行存儲。

事件執行
  事件執行時,document上綁定事件ReactEventListener.dispatchEvent會對事件進行分發,根據之前存儲的類型(type)和組件標識(_rootNodeID)找到觸發事件的組件。ReactEventEmitter利用EventPluginHub中注入(inject)的plugins(例如:SimpleEventPluginEnterLeaveEventPlugin)會將原生的DOM事件轉化成合成的事件,然后批量執行存儲的回調函,回調函數的執行分為兩步,第一步是將所有的合成事件放到事件隊列里面,第二步是逐個執行。需要注意的是,瀏覽器原生會為每個事件的每個listener創建一個事件對象,可以從這個事件對象獲取到事件的引用。這會造成高額的內存分配,React在啟動時就會為每種對象分配內存池,用到某一個事件對象時就可以從這個內存池進行復用,節省內存。

  再回到我們剛開始的問題,現在看起來就很沒有很費解了,之所以會出現上面的問題是因為我們混用了React的事件機制和DOM原生的事件機制,認為通過:

handleClickQr(e) {
    e.stopPropagation();
}

就能阻止原生的事件傳播,其實在事件委托的情形下是不能實現這一點的。當然解決的辦法也不復雜,不要將React事件和DOM原生事件混用。

componentDidMount() {
  document.body.addEventListener("click", e => {
    this.setState({
      active: false,
    });
  });
 
  document.querySelector(".code").addEventListener("click", e => {
    e.stopPropagation();
  })
}

componentWillUnmount() {
  document.body.removeEventListener("click");
  document.querySelector(".qr").removeEventListener("click");
}

或者通過事件原件對象中的target進行判斷:

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

都可以解決異常關閉的問題。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82126.html

相關文章

  • 談談React事件機制和未來(react-events)

    摘要:另外第三方也可以通過的事件插件機制來合成自定義事件,盡管很少人這么做。抽象跨平臺事件機制。打算干預事件的分發。事件是的一個自定義事件,旨在規范化表單元素的變動事件。 showImg(https://segmentfault.com/img/remote/1460000019961124?w=713&h=307); 當我們在組件上設置事件處理器時,React并不會在該DOM元素上直接綁定...

    TNFE 評論0 收藏0
  • React深入】React事件機制

    摘要:給注冊原生事件回調為統一的事件分發機制。根據元素唯一標識和事件類型從中取出回調函數返回帶有合成事件參數的回調函數總流程將上面的四個流程串聯起來。可見,回調函數是直接調用調用的,并沒有指定調用的組件,所以不進行手動綁定的情況下直接獲取到的是。 關于React事件的疑問 1.為什么要手動綁定this 2.React事件和原生事件有什么區別 3.React事件和原生事件的執行順序,可以混...

    philadelphia 評論0 收藏0
  • 結合源碼徹底理解 react事件機制原理 01 - 對事件機制的初步理解和驗證

    摘要:前言這是事件機制的第一篇,主要內容有表象理解,驗證,意義和思考。因為合成事件的觸發是基于瀏覽器的事件機制來實現的,通過冒泡機制冒泡到最頂層元素,然后再由統一去處理。合成事件的阻止冒泡不會影響原生事件。 showImg(https://segmentfault.com/img/bVbtvP2?w=800&h=420); 前言 這是 react 事件機制的第一篇,主要內容有:表象理解,驗證...

    muddyway 評論0 收藏0
  • 淺談React事件機制

    摘要:事件簡介事件是合成事件,所有事件都自動綁定到最外層上。支持事件的冒泡機制,我們可以使用和來中斷它。這樣做簡化了事件處理和回收機制,效率也有很大提升。事件類型合成事件的事件類型是原生事件類型的一個子集。 React事件簡介 React事件是合成事件,所有事件都自動綁定到最外層上。因為Virtual DOM 在內存中是以對象的形式存在的,所以React 基于 Virtual DOM 實現了...

    moven_j 評論0 收藏0
  • 淺談React事件機制

    摘要:事件簡介事件是合成事件,所有事件都自動綁定到最外層上。支持事件的冒泡機制,我們可以使用和來中斷它。這樣做簡化了事件處理和回收機制,效率也有很大提升。事件類型合成事件的事件類型是原生事件類型的一個子集。 React事件簡介 React事件是合成事件,所有事件都自動綁定到最外層上。因為Virtual DOM 在內存中是以對象的形式存在的,所以React 基于 Virtual DOM 實現了...

    MyFaith 評論0 收藏0

發表評論

0條評論

lavnFan

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<