React類,方法綁定(第三部分)

這是React和ECMAScript6/ECMAScript7結合使用系列文章的第三篇。javascript

下面是全部系列文章章節的連接:html

本篇文章Github源碼web

React JS

你在看上一篇文章中的CartItem render 方法中使用{this.increaseQty.bind(this)}代碼時,你確定會以爲困惑。gulp

若是咱們嘗試將{this.increaseQty.bind(this)}代碼替換成{this.increaseQty},咱們將在瀏覽器控制檯中發現以下錯誤:Uncaught TypeError: Cannot read property 'setState' of undefined.

cover

這是由於咱們當咱們調用一個用那種方法綁定的方法時,this不是類它自己,this未定義。相反,若是在案例中,React.createClass()全部的方法將會自動綁定對象的實例。這多是一些開發者的直覺。

No autobinding was the decision of React team when they implemented support of ES6 classes for React components. You could find out more about reasons for doing so in this blog post.

React team經過ES6來實現對React 組建的支持時,沒有設置自動綁定是React team的一個決定。在這篇博客中你能發現更多關於爲何這麼處理的緣由。

如今讓咱們來看看在你的JSX案例中,使用ES6類建立的方法的多種調用方法。我所考慮到的多種不一樣的方法都在這個GitHub repository

Method 1. 使用Function.prototype.bind().

以前咱們已經見到過:

export default class CartItem extends React.Component {
    render() {
        <button onClick={this.increaseQty.bind(this)} className="button success">+</button>
    }
}

當任何ES6的常規方法在方法原型中進行this綁定時,this指向的是類實例。若是你想了解更多Function.prototype.bind(),你能夠訪問這篇MDN博客

Method 2. 在構造函數中定義函數

此方法是上一個與類構造函數的用法的混合:

export default class CartItem extends React.Component {

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

    render() {
        <button onClick={this.increaseQty} className="button success">+</button>
    }
}

你不要再次在JSX代碼的其它地方進行綁定,可是這將增長構造函數中的代碼量。

Method 3. 使用箭頭函數和構造函數

ES6 fat arrow functions preserve this context when they are called. We could use this feature and redefine increaseQty() inside constructor in the following way:

當方法被調用時,ES6 fat arrow functions會保留上下文。咱們能使用這個特徵用下面的方法在構造函數中重定義increaseQty()函數。

export default class CartItem extends React.Component {

    constructor(props) {
        super(props);
        this._increaseQty = () => this.increaseQty();
    }

    render() {
        <button onClick={_this.increaseQty} className="button success">+</button>
    }
}

Method 4. 使用箭頭函數和ES2015+類屬性

另外,你能夠使用ES2015+類屬性語法和箭頭函數:

export default class CartItem extends React.Component {

    increaseQty = () => this.increaseQty();

    render() {
        <button onClick={this.increaseQty} className="button success">+</button>
    }
}

屬性初始化和Method 3中的功能同樣。

警告: 類屬性還不是當前JavaScript標準的一部分。可是你能夠在Babel中自由的使用他們。你能夠在這篇文章中瞭解更多類屬性的使用。

Method 5. 使用 ES2015+ 函數綁定語法.

最近,Babel介紹了Function.prototype.bind()::的使用。在這裏我就不深刻細節講解它工做的原理。有不少其它的小夥伴已經有很完美的解釋。你能夠Google搜索blog 2015 function bind瞭解更多細節。

下面是ES2015+函數綁定的使用:

export default class CartItem extends React.Component {

    constructor(props) {
        super(props);
        this.increaseQty = ::this.increaseQty;
        // line above is an equivalent to this.increaseQty = this.increaseQty.bind(this);
    }

    render() {
        <button onClick={this.increaseQty} className="button success">+</button>
    }
}

強調:這個特性是高度的實驗,使用它你得本身承擔風險。

Method 6. 在調用方法的方使用 ES2015+ 函數綁定語法.

You also have a possibility to use ES2015+ function bind syntax directly in your JSX without touching constructor. It will look like:

你也能夠直接在非構造函數裏面的JSX裏面直接使用ES2015+函數綁定。效果以下:

export default class CartItem extends React.Component {
    render() {
        <button onClick={::this.increaseQty} className="button success">+</button>
    }
}

很是簡潔,惟一的缺點是,這個函數將在每一個後續渲染組件上從新建立。這不是最佳的。更重要的是,若是你使用像PureRenderMixin的東西將會出現。

結論

在這篇文章中,咱們已經發現了多種React組建類方法的綁定方法。

參考文檔

掃碼申請加入全棧部落
相關文章
相關標籤/搜索