React事件綁定總結


需要綁定的原因
 
  事件綁定目的,就是事件的作用域的轉移。
  問題是,react生成出來的組件,this還不能指向自身嗎?
<button onClick={this.plus}>plus</button>
  plus函數上的this,是事件響應時的上下文(window),並不是當前組件實例!
  先來看看bind方法的定義:“bind()方法創建一個新的函數, 當這個新函數被調用時其this置為提供的值”,什么意思呢,看代碼:
var module = { x: 42, getX: function() { return this.x; } } var unboundGetX = module.getX; console.log(unboundGetX()); // 調用的對象是window,所以里面的this.x => window.x // expected output: undefined

var boundGetX = unboundGetX.bind(module); console.log(boundGetX()); // 但是bind之后,會將this的值置為module提供的值 // expected output: 42

  所以代碼修改為 this.plus.bind(this)之后,不過執行時的上下文是什么,函數的內部的this,始終指向組件提供的值。

 
 
選擇綁定方法的目的
 
  綁定的方法有好多種,為什么需要挑選呢?我們首先要了解到:
  • DOM 是一個獨立於語言的文檔接口 API。在瀏覽器中,該 API 是用 JavaScript 實現的。但瀏覽器通常把DOM 和 JavaScript 分開實現。所以每次 JavaScript 訪問 DOM 都會伴隨着巨大的開銷。
  • bind() 會創建一個綁定了作用域的函數實例。於是,從原型中實現一個實例,相當於拷貝了一份同樣的函數,這是一種巨大的浪費。React想要把系統的方法關聯到DOM上,我們需要最優的方法進行綁定。
  而React事件系統對DOM進行了改進,有一套高效的事件的
  • 注冊
  • 存儲
  • 分發
  • 重用
的機制,得到了優秀的效果:
  • 事件委托:react組件聲明的事件都會轉換成DOM原生事件
  • 事件冒泡:以隊列的形式,可以回溯父組件
  • 合成事件:並不是單純的使用DOM原生事件
  • 對象池:合理管理事件對象,內存分配,垃圾回收
 
 
實現
  • bind方法
    • 每次重新渲染時,都會生成一個新的函數實例保存在listenerBank中
      • 數量多時極其浪費內存。
      • 如果是子組件的props,則會導致子組件重新渲染
    • 用默認參數event來解決,如【箭頭函數-函數上】,它們會在有event參數的情況下綁定到同一個函數上
<button onClick={this.handleEdit.bind(this, param)}>編輯</button>
  • 箭頭函數上調用
    • 實際效果同bind方法,同樣會造成重新綁定問題
    • 可以帶參數,但是需要把參數寫兩次,不划算
<button onClick={(param) => this.handleEdit(param)}>編輯</button>
  • 構造器內部聲明
    • 官方推薦,雖然代碼量多
    • 事件只會生成一個
constructor(props){ super(props); this.handleEdit = this.handleEdit.bind(this); }
  • 箭頭函數聲明
    • 寫法簡單
    • 只會生成一個
    • 不能帶參數,帶參數就要寫成bind方式
const handleEdit = (e) => { console.log(e) }
  • 雙冒號語法
    • ::的意思是,綁定左值和右值
    • 相當於.bind(this),但是不能帶參數,不推薦
<button onClick={::this.click}></button
 
當組件的事件數量極多時,用【構造器內部聲明】方法,否則就犧牲性能來換取便捷,有參數就用【bind方法】,沒有就用【箭頭函數聲明】。這是又一個性能與業務平衡的例子。
 
 
思考
 
  • 為什么在VUE中的事件不需要綁定?
<button v-on:click="say('what')">Say what</button
  來看看官方原文:
  印證了那句話:VUE是保時捷,react是組裝車。
 
  • jQuery需要事件綁定嗎?
  需要。但是為了不破壞DOM的結構,並不是直接綁定在DOM上,而是通過一種緩存的方式監聽數據。
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM