古老的React mixins

今天在翻看博客時,忽然發(fā)現(xiàn)有的博主在討論render props時,說到了React mixins。由于自己使用React時間不是特別長,所以對于早前的React版本的語法不是很熟悉,所以補充一下。順便做一個小的系列文章:

  1. 古老的React mixins
  2. HOC(高階組件)
  3. render props
  4. React Hooks

什么是React mixins ?

mixins(混合)是指定義一個對象,讓組件去繼承該對象的方法和狀態(tài)的過程,該對象也被稱為混入(混合)對象。若組件和被繼承的混合對象具有相同的生命鉤子函數(shù),并且在執(zhí)行該生命鉤子函數(shù)時,混合對象的函數(shù)會優(yōu)先執(zhí)行,然后再到組件內相同函數(shù)執(zhí)行,但僅限于生命鉤子函數(shù)。

另外,組件內不允許有和混合對象相同命名的方法(非生命鉤子函數(shù)),如例子中的handlAction,否則會報錯:

ReactClassInterface: You are attempting to define `handlAction` on your component more than once. This conflict may be due to a mixin.
// 混合
const mixinCommon = {
    componentWillMount: function() {
        console.log("mix componentWillMount!");    //優(yōu)先執(zhí)行
    },
    handlAction:function(){
        console.log("mix action!");     //該方法不允許再從組件中重構,否則會報錯
    }
}

var HelloWorld = React.createClass({
    mixins: [mixinCommon],
    componentWillMount: function() {
        console.log("HelloWorld componentWillMount!"); //仍會執(zhí)行
    },
    componentDidMount: function() {
            this.handlAction();      //調用mixinCommon的方法
        },
        render: function() {
            return <h1>Hello World!</h1>;
        }
});
ReactDOM.render(<HelloWorld />,document.getElementById("example"));

需要注意的是:ES6 本身是不包含混入支持的。因此,如果你使用 class 關鍵字創(chuàng)建組件,那就不能使用混入功能了。我們現(xiàn)在在使用React的時候大部分都是使用class關鍵字創(chuàng)建組件,很少使用createClass來創(chuàng)建組件了。正因為如此,我們現(xiàn)在幾乎很少使用到mixins了。

React mixins在解決什么問題,本身存在什么問題 ?

回答上述問題之前,我們再來看一個mixins的典型??:

import React from 'react'
import ReactDOM from 'react-dom'

// mixin 中含有了你需要在任何應用中追蹤鼠標位置的樣板代碼。
// 我們可以將樣板代碼放入到一個 mixin 中,這樣其他組件就能共享這些代碼
const MouseMixin = {
  getInitialState() {
    return { x: 0, y: 0 }
  },

  handleMouseMove(event) {
    this.setState({
      x: event.clientX,
      y: event.clientY
    })
  }
}

const App = React.createClass({
  mixins: [ MouseMixin ],
  
  render() {
    const { x, y } = this.state

    return (
      <div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>
        <h1>The mouse position is ({x}, {y})</h1>
      </div>
    )
  }
})

ReactDOM.render(<App/>, document.getElementById('app'));

很簡單,如果有好幾處地方需要使用鼠標的X和Y坐標,只需要輕松的將 MouseMixin 混入他們的組件中,并通過 this.state 屬性獲得鼠標的 x 和 y 坐標。所以mixin很顯然是為了解決代碼復用的問題。

但是這種解決方式并不是非常完美無瑕,具體原因總結如下:

  • ES6 class不支持 mixins。
  • 不夠直接。minxins 改變了 state,因此也就很難知道一些 state 是從哪里來的,尤其是當不止存在一個 mixins 時。
  • 名字沖突。兩個要更新同一段 state 的 mixins 可能會相互覆蓋。createClass API 會對兩個 mixins 的 getInitialState 是否具有相同的 key 做檢查,如果具有,則會發(fā)出警告,但該手段并不牢靠。

所以為了解決上述問題,在React社區(qū)有人開始大量使用高階組件HOC。參考下篇文章:React HOC(高階組件)。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 作為一個合格的開發(fā)者,不要只滿足于編寫了可以運行的代碼。而要了解代碼背后的工作原理;不要只滿足于自己的程序...
    六個周閱讀 8,675評論 1 33
  • 深入JSX date:20170412筆記原文其實JSX是React.createElement(componen...
    gaoer1938閱讀 8,183評論 2 35
  • 40、React 什么是React?React 是一個用于構建用戶界面的框架(采用的是MVC模式):集中處理VIE...
    萌妹撒閱讀 1,185評論 0 1
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內容,還有我對于 Vue 1.0 印象不深的內容。關于...
    云之外閱讀 5,177評論 0 29
  • 事件系統(tǒng) 合成事件的綁定方式 Test 合成事件的實現(xiàn)機制:事件委派和自動綁定。 React合成事件系統(tǒng)的委托機制...
    cheneyg916閱讀 456評論 0 1

友情鏈接更多精彩內容