React 與 bind this 的一些心得

Hyman Chen
ReactMaker
Published in
4 min readAug 24, 2017

我們都知道在撰寫 React class 的時候常常需要使用 bind(this) 這行語法來讓property與 this 保持關係。

於是我開始動手做點實驗,寫一支簡單的 JS 程式來探討 class 內部 property 能不能呼叫 this

class Animal {
constructor(name) {
this.name = name;
}
run() {
console.log(`${this.name} has run 100 cm`);
}
}

const dog = new Animal('poke');
dog.run();

這時候我們會得到輸出是

poke has run 100 cm

我們寫了一個 ES6 的 class 可以在裡面取得 this,但是為什麼 React 內部的 property 確不能夠取得 this 呢?

我查了一些網路上的文章

當使用 extend React.Component 的方式去宣告元件的時候,React 確實會綁定 this 到元件內,但是卻有以下特定的地方才會被綁進去

  1. 生命周期函式,例如 componentDidMount 等等
  2. render

其他自己定義的 property 就不會被綁入 this ,而且 this 會被指到 windows 這個全域上。

提供5個解法

這5個解法可以挑一種使用就可以,每一種都有不同的優缺點,大家可以依照自己使用的情境來挑選。喜歡看原文的可以點下面的連結

  1. 不要用 class 建構React元件的方式,改用 Rreact.createClass

我不建議使用這種方式,因為現在幾乎都是用 ES6 來寫,別自廢武功阿….

2. 在 render 內綁定 this

<Input onChange={this.handleChange.bind(this)} />

其實我也不建議用這種方式,據說會有效能的影響

3. 在 constructor 裡面綁定

constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}

這是很常見的方法,缺點就是要寫多一點點的程式,因為你每次做一個property function 都要 bind 一次。

4. 使用箭頭函式在 render 內

<Input onChange={(e) => this.handleChange(e)} />

據說也是有效能的 issue ,各位也可以斟酌使用

5. 在宣告 property 的時候就使用箭頭函數

handleChange = (e) => {
this.XXXX
}

在上面這麼多解法,這個應該算是比較好的解法,不用多寫一行程式去綁定,也不用在 render 裡面綁定降低效能。

總結

在了解了 React 這麼多種綁定 this 的方法之後,應該也會跟我一樣選擇使用箭頭函數來宣告 property 吧!!不過在使用箭頭函數之前必須要開啟 babel 的 transform-class-properties or enable stage-2 in Babel 這兩個功能,所以如果不太會設定 webpack 或是 babel 的同學可以建議直接用我們做好的 startKit 直接使用,裡面就已經有箭頭函數的功能了!

--

--