Reactjs Mixins

拋磚引玉

實現一個日誌功能。編程

  • 組件在掛載前打印 Component will mount
  • 組件掛載後打印 Component did mount

不能忍受的寫法

var AComponent = React.createClass({
    componentWillMount: function () {
        console.log('Component will mount');
    },
    componentDidMount: function () {
        console.log('Component did mount');
    },
    render: function () {
        return (
            <div>AComponent</div>
        )
    }
});

var BComponent = React.createClass({
    componentWillMount: function () {
        console.log('Component will mount');
    },
    componentDidMount: function () {
        console.log('Component did mount');
    },
    render: function () {
        return (
            <div>BComponent</div>
        )
    }
});

看到上面的代碼,直接吐血而亡啊,寫的是什麼幾把玩意兒。還好只寫了兩個組件,要是多個組件,相同的代碼就會重複多遍。相信你們看到上面的代碼也會發現一個致命的問題:可維護性太差差差!數組

改進

相信你們都不會寫出上面的代碼,若是真有人會那樣寫,請容許我呵呵你。通常都會抽出公共的部分。this

var Log = {
    componentWillMount: function () {
        console.log('Component will mount');
    },
    componentDidMount: function () {
        console.log('Component did mount');
    }
};


var AComponent = React.createClass({
    componentWillMount: function () {
        Log.componentWillMount();
    },
    componentDidMount: function () {
        Log.componentDidMount();
    },
    render: function () {
        return (
            <div>AComponent</div>
        )
    }
});

var BComponent = React.createClass({
    componentWillMount: function () {
        Log.componentWillMount();
    },
    componentDidMount: function () {
        Log.componentDidMount();
    },
    render: function () {
        return (
            <div>BComponent</div>
        )
    }
});

看起來挺完美的,實際上仍是有個問題:代碼的耦合性太強!像這種日誌功能應該同業務分離,不該該直接出如今業務代碼中。若是作過Java開發,應該很容易想到一個概念:AOP—面向切面編程。spa

Mixins

利用React的Mixins,編寫的代碼就像這樣的:日誌

var LogMixin = {
    componentWillMount: function () {
        console.log('Component will mount');
    },
    componentDidMount: function () {
        console.log('Component did mount');
    }
};

var AComponent = React.createClass({
    mixins: [LogMixin],
    render: function () {
        return (
            <div>AComponent</div>
        )
    }
});

var BComponent = React.createClass({
    mixins: [LogMixin],
    render: function () {
        return (
            <div>BComponent</div>
        )
    }
});

Mixins有點相似AOP。所謂的mixins就是將組件裏的方法抽出來。實際上Mixins裏的this是指向組件的,使用了Mixins之後,組件也能夠調用Mixins裏的方法。code

組件調用Mixins方法

var Mixin = {
    log:function(){
       console.log('Mixin log');
    }
};

var Component = React.createClass({
    mixins: [Mixin],
    componentWillMount: function () {
        this.log();
    },
    render: function () {            
        return (
            <div>Component</div>
        )
    }
});

控制檯打印:component

$ Mixin log

生命週期方法

Mixins裏也能夠編寫組件生命週期的方法,須要注意的是:Mixins裏的方法並不會覆蓋組件的生命週期方法,會在先於組件生命週期方法執行。blog

var Mixin = {
    componentWillMount: function () {
        console.log('Mixin Will Mount');
    }
};

var Component = React.createClass({
    mixins: [Mixin],
    componentWillMount: function () {
        console.log('Component Will Mount');
    },
    render: function () {
        return (
            <div>Component</div>
        )
    }
});

控制檯打印:生命週期

$ Mixin Will Mount
$ Component Will Mount

使用多個Mixin

組件也可使用多個Mixin圖片

var AMixin = {
    componentWillMount: function () {
        console.log('AMixin Will Mount');
    }
};

var BMixin = {
    componentWillMount: function () {
        console.log('BMixin Will Mount');
    }
};

var Component = React.createClass({
    mixins: [AMixin,BMixin],
    componentWillMount: function () {
        console.log('Component Will Mount');
    },
    render: function () {
        return (
            <div>Component</div>
        )
    }
});

控制檯打印:

$ AMixin Will Mount
$ BMixin Will Mount
$ Component Will Mount

數組引入的順序,決定了Mxins裏生命週期方法的執行順序。

不容許重複

除了生命週期方法能夠重複之外,其餘的方法都不能夠重複,不然會報錯

情景1

var AMixin = {
    log: function () {
        console.log('AMixin Log');
    }
};

var BMixin = {
    log: function () {
        console.log('BMixin Log');
    }
};

var Component = React.createClass({
    mixins: [AMixin,BMixin],
    render: function () {
        return (
            <div>Component</div>
        )
    }
});

情景2

var Mixin = {
    log: function () {
        console.log('Mixin Log');
    }
};

var Component = React.createClass({
    mixins: [Mixin],
    log:function(){
        console.log('Component Log');
    },
    render: function () {
        return (
            <div>Component</div>
        )
    }
});

以上兩種情景,都會報錯,控制信息以下,因此使用的時候要當心了

圖片描述

相關文章
相關標籤/搜索