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

資訊專欄INFORMATION COLUMN

淺析React之事件系統(二)

villainhr / 1390人閱讀

摘要:因為阻止事件冒泡的行為只能用于合成事件中,沒法阻止原生事件的冒泡。同時的創建和冒泡是在原生事件冒泡到最頂層的之后的。淺析之事件系統一

上篇文章中,我們談到了React事件系統的實現方式,和在React中使用原生事件的方法,那么這篇文章我們來繼續分析下,看看React中合成事件和原生事件混用的各種情況。

上一個例子

在上篇文章中,我們舉了個例子。為了防止大家不記得,我們來看看那個例子的代碼。

class App extends React.Component {

  constructor(props){
    super(props);
    
    this.state = {
      show: false
    }
    
    this.handleClick = this.handleClick.bind(this)
    this.handleClickImage = this.handleClickImage.bind(this);
  }
  
  handleClick(){
   this.setState({
     show: true
   })
  }
  
  componentDidMount(){
    document.body.addEventListener("click", e=> {
      this.setState({
        show: false
      })
    })
  }
  
  componentWillUnmount(){
    document.body.removeEventListener("click");
  }
  
  handleClickImage(e){
    console.log("in this ")
    e.stopPropagation();
  }
  
  render(){
    return (
      
) } } ReactDOM.render(, document.getElementById("root"));

這有什么問題呢? 問題就在于,如果我們點擊image的內部依舊可以收起Image,那么這是為什么呢?這是因為我們及時點擊了Image的內部,body上綁定的事件處理器依舊會執行,這樣就讓我們的image收起來了。那我們如果不想讓image收起來改怎么做呢?

首先的想法是停止冒泡,如果我們在img-container中就停止冒泡了是不是就可以讓image不消失了呢?比如這樣:

...
handleClickImage(e){
    e.preventDefault();
    e.stopPropagation();
  }
  
  render(){
    return (
      
) } ...

Open In CodePen

在這里我們定義一個handleClickImage的方法,在其中我們執行取消默認行為和停止冒泡。那是似乎效果并不是我們想要的。因為阻止React事件冒泡的行為只能用于React合成事件中,沒法阻止原生事件的冒泡。同樣用React.NativeEvent.stopPropagation()也是無法阻止冒泡的。

如何解決這樣的問題呢?首先,盡量的避免混用合成事件和原生事件。需要注意的點是:

阻止react 合成事件冒泡并不會阻止原生時間的冒泡,從上邊的例子我們已經看到了,及時使用stopPropagation也是無法阻止原生時間的冒泡的。

第二點需要注意的是,取消原生時間的冒泡會同時取消React Event。并且原生事件的冒泡在react event的觸發和冒泡之前。同時React Event的創建和冒泡是在原生事件冒泡到最頂層的component之后的。我們來看這個例子:

class App extends React.Component {
  
  render(){
   return ;
  }
}

class GrandPa extends React.Component {
  constructor(props){
      super(props);
      this.state = {clickTime: 0};
      this.handleClick = this.handleClick.bind(this);
  }
  
 handleClick(){
   console.log("React Event grandpa is fired");
  this.setState({clickTime: new Date().getTime()})
};
  
  componentDidMount(){
    document.getElementById("grandpa").addEventListener("click",function(e){
      console.log("native Event GrandPa is fired");
    })
  }
  
  render(){
    return (
      

GrandPa Clicked at: {this.state.clickTime}

) } } class Dad extends React.Component { constructor(props){ super(props); this.state = {clickTime:0}; this.handleClick=this.handleClick.bind(this); } componentDidMount(){ document.getElementById("dad").addEventListener("click",function(e){ console.log("native Event Dad is fired"); e.stopPropagation(); }) } handleClick(){ console.log("React Event Dad is fired") this.setState({clickTime: new Date().getTime()}) } render(){ return (

Dad Clicked at: {this.state.clickTime}

) } } class Son extends React.Component { constructor(props){ super(props); this.state = {clickTime:0}; this.handleClick=this.handleClick.bind(this); } handleClick(){ console.log("React Event Son is fired"); this.setState({clickTime: new Date().getTime()}) } componentDidMount(){ document.getElementById("son").addEventListener("click",function(e){ console.log("native Event son is fired"); }) } render(){ return (

Son Clicked at: {this.state.clickTime}

) } } ReactDOM.render(, document.getElementById("root"));

Open in CodePen

在這個例子中我們有三個component,Son Dad,Grandpa。同時定義了React Event handler 和 native event handler,并在Dad的native Event handler中stopPropagation,當我們點擊Son or Dad component的時候會發現,React Event handler并沒有被trigger。
console里的output為:

"native Event son is fired"
"native Event Dad is fired"

這就說明native Event的停止冒泡可以阻斷所有的React Event。所以即使我們是在Dad上停止冒泡的,依舊阻斷了Son上的React Event。

同時如果我們把dad上的stopPropagation remove掉我們會看到如下結果:

"native Event son is fired"
"native Event Dad is fired"
"native Event GrandPa is fired"
"React Event Son is fired"
"React Event Dad is fired"
"React Event grandpa is fired"

這就說明React的合成時間是在原生事件冒泡到最頂層組件結束后才創建和冒泡的,也是符合React的原理,因為在是實現的時候React只是將一個Event listener 掛在了最頂層的組件上,其內部一套自己的機制進行事件的管理。

淺析React之事件系統(一)

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

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

相關文章

  • 淺析React事件系統(一)

    摘要:合成事件的使用方式在中不會把所有的事件處理器綁定到相應的真實的節點上,而是使用一個統一的事件監聽器,把所有的事件綁定在最外層。在之前開發者需要為了優化性能需要自己來優化自己的事件處理器的代碼,現在幫助你完成了這些工作。 大家周末好,2016年的最后幾篇文章開始寫到了React的一些東西,那么最近就來一些圖表君對于React的簡單總結和理解,那么今天就開始第一篇,說一說React的事件系...

    chemzqm 評論0 收藏0
  • 淺析webpack源碼convert-argv模塊(

    摘要:接下來我看看一下函數我們先按照分支走為讀取是里的對象,饒了這大的一個圈子,那么接下來一起來看一看對你的輸入配置做了怎么樣的處理吧 打開webpeck-cli下的convert-argv.js文件 // 定義options為空數組 const options = []; // webpack -d 檢查 -d指令 if (argv.d) { //... } ...

    lemon 評論0 收藏0
  • 淺析 web 前端 MVVM

    摘要:它由微軟架構師和開發,通過利用微軟圖形系統和的互聯網應用派生品的特性來簡化用戶界面的事件驅動程序設計。微軟的和架構師之一于年在他的博客上發表了。更改時會得到提醒這個情況是一個單向流。 前言 記得四個月前有一次面試,面試官問我 MVVM 是什么,MVVM 的本質是什么。我大腦一片混亂,那時我對 MVVM 的認知就只是雙向綁定和Vue,以這個關鍵字簡單回答了幾句,我反問 MVVM 的本質是...

    VincentFF 評論0 收藏0
  • 最近遇到的前端面試題(2017.03.08更新版)

    摘要:通過管理組件通信通過驅動視圖比較差異進行更新操作作者第七頁鏈接來源知乎著作權歸作者所有,轉載請聯系作者獲得授權。達到無刷新的效果。對象的狀態不受外界影響。對象代表一個異步操作,有三種狀態進行中已完成,又稱和已失敗。 以下問題解釋非本人原創,是根據面試經驗整理后覺得更容易理解的解釋版本,歡迎補充。 一. 輸入url后的加載過程 從輸入 URL 到頁面加載完成的過程中都發生了什么 計算機...

    linkFly 評論0 收藏0
  • 最近遇到的前端面試題(2017.03.08更新版)

    摘要:通過管理組件通信通過驅動視圖比較差異進行更新操作作者第七頁鏈接來源知乎著作權歸作者所有,轉載請聯系作者獲得授權。達到無刷新的效果。對象的狀態不受外界影響。對象代表一個異步操作,有三種狀態進行中已完成,又稱和已失敗。 以下問題解釋非本人原創,是根據面試經驗整理后覺得更容易理解的解釋版本,歡迎補充。 一. 輸入url后的加載過程 從輸入 URL 到頁面加載完成的過程中都發生了什么 計算機...

    Nosee 評論0 收藏0

發表評論

0條評論

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