個人總結:
問: 請給我講一下React中的事件處理為什么要bind this?
答: 好的,比如說我寫了一個類組件,有個onClick屬性 ,onClick={ this.fun },如果不bind肯定是不行的,下面講一下為什么要bind this:
首先我們知道React是通過創建虛擬DOM 然后將虛擬DOM生成真實的DOM 最后插入到頁面中,
而React生命周期中render方法的作用就是將虛擬DOM渲染成真實DOM
看一下這篇文章 https://github.com/hujiulong/blog/issues/4
這里提到了render的實現 render將"on+大寫字母"開頭的事件屬性 轉化為"on+小寫字母"開頭的屬性 ,並生成真實DOM,生成真實DOM的同時
把這個函數賦值過去。
( 這篇文章只是一個簡要的示例,實際情況更為復雜)
在JSX語法中: onClick={ function } onClick這個屬性本身只是一個"中間變量"。將函數賦值給onClick這個中間變量,后面要進行JSX語法轉化,將JSX組件轉換成Javascript對象,進而轉換成真實DOM。
把onClick作為中間變量,指向一個函數的時候,后面的一系列處理中,使用onClick這個中間變量所指向的函數,里面的this會自然丟失掉了,不是再指向react組件實例了。
預備知識點:JS中的this是由函數調用者調用的時候決定的。
obj:{
fun:function(){ console.log(this) }
}
obj.fun() //obj
let var = obj.fun()
var() // window||undefined
在類組件的render函數中 將函數fun賦給真實的屬性的時候 有點類似於做了這樣的操作:
class Cat { sayThis () { console.log(this); // 這里的 `this` 指向誰? } exec (cb) { cb(); } render () { this.exec(this.sayThis); } }
const cat = new Cat(); cat.render(); // 輸出結果是什么?
當把一個函數作為callback傳遞給另一個函數的時候,這個函數的this一定是會丟失的,
相當於是 let var = function () { ..} ; var();
所以會出現這種問題。
延伸一下,為什么React沒有自動的把bind集成到render方法中呢?
答:因為render函數會被多次調用,每次都要bind會影響性能,所以官方建議你自己在constructor中手動bind達到性能優化。