揭秘React Class組件的三個小細節


問題一:為啥要用bind 和 箭頭函數

剛接觸React,基本上都會遇到一個問題:就是在事件處理函數里面用到了this,但是 這個this是undefined,導致報錯。

然后這個問題的原因,常見說法是:“React事件處理函數是沒有默認綁定this的”,雖然沒有錯,但是沒有get到真正的點。

原因:

  首先,這是 JavaScript 函數和this工作原理導致的,並不是React的問題,事件處理的那個 props——onClick 接收到了函數,卻不知道執行上下文

  this是當前函數運行所在的環境,也就是總是指向函數運行所在的那個對象。

解決方案:

  1、使用bind綁定

  2、使用箭頭函數。 

 

先看看關於this的一個例子

 1 var obj = {
 2     foo: function() {
 3         console.log(this)
 4     }      
 5 }
 6 
 7 var foo = obj.foo
 8 
 9 obj.foo()  // 打印結果是  obj對象
10 foo()      // 打印結果是  undefined

再看一個用 class 模擬一個和React相似的例子:

 1 let onClick = null
 2 
 3 class CustomReact {
 4     handleClick() {
 5         console.log(this)
 6     }
 7     render() {  
 8      onClick = this.handleClick 
 9    } 
10 } 
11 var c = new CustomReact() 
12 c.render() 
13 
14 onClick() // 打印出來的是 undefined

 

因為在賦值的時候,丟失了它的 執行上下文,只賦值過去了一個普通函數

所以我們只有“包裝”一個含有執行上下文的函數,然后賦值給新變量,那么這個變量執行的時候就能找到它的執行上下文。

“包裝”的方法就有 bind 和 箭頭函數

 

然后用處理React的方法,用bind稍作修改

/* 把 onClick = this.handleClick
*  改成 onClick = this.handleClick.bind(this)
*  或者 把 handleClick 改為 handleClick = () => {}
*  然后再 執行 onClick ,打印的就會是CustomReact 對象
*/

  

問題二: class 中,handleClick() {}  和 handleClick = () => {} 的區別

區別一:前者是方法的簡寫,所以還是function函數,后者是箭頭函數

區別二:前者是原型方法,后者是實例方法。

 1 class Test {
 2       instanceFunc = () => {}  // 實例方法
 3   
 4       protoFunc() {} // 原型方法。這是ES6對象方法的簡寫
 5  
 6 }
 7 
 8 // 上面代碼等同於 
 9   
10 function Test() {
11     this.instanceFunc = function () {}
12 }
13 
14 Test.prototype = {
15     constructor: Test
16     protoFunc: function() {}
17 }

 

問題三:在render 中綁定 this 和 在外面綁定的區別?

在 render 中綁定this的時候,不管bind還是箭頭函數都會新創建一個函數,這會可能會破壞它本身嚴格比較的優化

 

 

 

 

 

相比較於這兩種,更推薦使用下面兩種用法

 

1、

this.handleClick = this.handleClick.bind(this)

.....

onClick={this.handleClick}

 

2、

handleClick = () => {}
....

onClickonClick={this.handleClick}

 


免責聲明!

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



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