React與ES6(三)ES6類和方法繫結

桃子紅了吶發表於2017-11-08

React與ES6系列:

  1. React與ES6(一)開篇介紹
  2. React和ES6(二)ES6的類和ES7的property initializer
  3. React與ES6(三)ES6類和方法繫結
  4. React與ES6(四)ES6如何處理React mixins

如果你看到前篇CartItemrender方法裡的這一句:{this.increaseQty.bind(this)}你可能會很意外為什麼要bind

如果把bind刪掉的話會怎麼樣呢?會報錯Uncaught TypeError: Cannot read property `setState` of undeined

這是因為this.increaseQtythis指向的不是類,而是undefined。ES6的類不支援自動繫結,不能像ES5那樣。比如React.createClass()這樣全部的內部方法都是自動繫結好了。

下面我們就看看ES6寫的React元件類如何繫結內部方法。

方法一、使用Function.prototype.bind()

class CartItem extends React.Component {

    render() {
        return (
            <p className="large-4 column">
                <button onClick={this.increaseQty.bind(this)} className="button success">+</button>
                <button onClick={this.decreaseQty.bind(this)} className="button alert">-</button>
            </p>
        );
    }
}

ES6的類本質就是Javascript方法,從Function的prototype裡繼承了bind()方法。所以當我們呼叫increaseQty()方法的時候,this指向了類的例項。你可以在MDN文件裡看到更多

方法二、使用在constructor裡定義的方法

這是方法一和constructor的混合使用:

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>
    }
}

這個方法就是把bind()方法從JSX定義裡換到了類的constructor裡。

方法三、使用箭頭方法和建構函式

ES6的胖箭頭方法被呼叫的時候保留了this指向的上下文。我們可以使用這一特性在建構函式裡重新定義increaseQty()方法。

export default class CartItem extends React.Component {
    constructor(props) {
        super(props);
        // this.state = {
        //     qty: props.initialQty,
        //     total: 0
        // };
        this._increaseQty = () => this.increaseQty();
    }

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

方法四、使用胖箭頭方法和ES2015的class property

export default class CartItem extends React.Component {

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

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

因此,類屬性非常的簡潔。

注意:類屬性不是當前Javascript的標準,但是Babel已經支援這個功能(stage 0)。你可以看這裡瞭解更多。

方法五、使用ES2015的方法繫結語法

Babel又加入了對一個語法糖的支援Function.prototype.bind()::。這裡就不介紹這個操作符是怎麼工作的了。

export default class CartItem extends React.Component {
    constructor(props) {
        super(props);
        this.increaseQty = ::this.increaseQty;
    }

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

最後

老外介紹的幾個方法有點地方差別都不大,有的甚至只是呼叫的地方從constructor換到了JSX裡。所以,有些就略去了,其他的可以看看。

歡迎加群互相學習,共同進步。QQ群:iOS: 58099570 | Android: 572064792 | Nodejs:329118122 做人要厚道,轉載請註明出處!

本文轉自張昺華-sky部落格園部落格,原文連結:http://www.cnblogs.com/sunshine-anycall/p/5888242.html,如需轉載請自行聯絡原作者


相關文章