使用高階組件替代Mixins

本文我們將主要討論如何使用高階組件的方式取代傳統的React Mixins。

Statement

作者:景莊,Web開發者,主要關注JavaScript、Node.js、React、Docker等。

源碼:本文的源代碼地址:https://github.com/wwsun/react-es6-tutorial

介紹

當使用React.createClass()的時候,你可能會使用到所謂的Mixins。使用Mixins允許我們在我們的React組件中混入一些附加的功能。 這個概念并不是React所獨有的,它也存在于普通的JS或其他語言的框架中。

如果是要使用ES6來編寫React組件的話,我們將不建議你使用React的mixin機制了。 本文并不會深入的探討為什么不建議使用mixin的原因。如果你感興趣的話,你可以通過如下的鏈接查看相關的資料:

React官方有關在ES6中使用mixins的博文

Mixins已死——Dan Abramov

下面我們將主要關注的是具體的例子。

使用高階組件替代Mixins

本文我們將繼續使用之前的代碼,并對代碼做一定的修改。通過本文,我們將能夠在頁面中顯示用戶在當前頁面停留的時間。

為什么能夠更好的進行說明,我們將不會修改CartItem組件的代碼。而是通過提供一些能夠包裹CartItem組件的組件, 并通過一些額外的功能來“增強”CartItem組件。這樣的組件我們稱之為高階組件(Higher-Order Component)。

這個概念聽起來可能有點含義模糊,隨著我們的深入,你將會理解的更透徹一點。

假設,我們有一個IntervalEnhance組件,我們在CartItem組件中導入它,并通過它來包裹原有的導出對象。

// src/components/cart-item.jsximportReactfrom'react';import{IntervalEnhance}from"./interval-enhance.jsx";// 1. 導入包裹組件classCartItemextendsReact.Component{// component code here}exportdefaultIntervalEnhance(CartItem);// 2. 包裹原有的CartItem組件

現在我們將來編寫這個IntervalEnhance組件。

// src/components/interval-enhance.jsximportReactfrom'react';// 1exportletIntervalEnhance=ComponsedComponent=>classextendsReact.Component{constructor(props){super(props);this.state={seconds:0// 2};}// 3componentDidMount(){this.interval=setInterval(this.tick.bind(this),1000);}// 3componentWillUnmount(){clearInterval(this.interval);}tick(){this.setState({seconds:this.state.seconds+1000});}render(){// 4return;}};

我們一一的來解釋上面幾處加注釋的代碼:

ComposedComponent => class extends React.Component- 這其實和定義返回類的函數一樣。 其中ComposedComponent是我們想要“增強”的組件(在上面的代碼中就是CartItem組件)。 通過使用export let IntervalEnhance我們可以導出整個函數為IntervalEnhance(也就是上面代碼中的CartItem)。 所以,上面的代碼也可以這么寫:

javascript let IntervalEnhance = function (ComposedComponent) { return class extends React.Component { // class methods here }; };

初始化組件的狀態(state),設置seconds的值為0。

組件的生命周期鉤子函數,用于期待能夠和暫停計數器。

最重要的一個部分。這行代碼將所有的state或props拿到我們的“增強器”組件中,然后轉移到CartItem組件中。 通過這種方式,CartItem組件將能夠訪問到this.state.seconds屬性。

最后一步是改變CartItem組件中的render方法。我們將直接向視圖中輸出this.state.seconds:

importReactfrom'react';import{IntervalEnhance}from"./interval-enhance.jsx";classCartItemextendsReact.Component{// component code hererender(){returnTimeelapsedforinterval:{this.props.seconds}ms;}}exportdefaultIntervalEnhance(CartItem);

現在我們可以瀏覽器中檢查結果了,我們將在頁面中看到一行文字,顯示用戶在當前頁面停留的時間。

注意:所有這一切并沒有改變CartItem組件的任何主體代碼(除了render方法)! 這就是為什么高階組件這么強大的原因!

裝飾器*

此外,ECMAScript的未來標準中還將引入裝飾器的概念,通過這種方法能夠更優雅的解決Mixin的問題, 本文不對未標準化的特性做過多的介紹。不過,代碼大致如下:

importReactfrom'react';import{IntervalEnhance}from"./interval-enhance";@IntervalEnhanceexportdefaultclassCartItemextendsReact.Component{// component code here}

PureRenderMixin呢?

如果你使用了諸如PureRenderMixin這樣的mixins,那么醬油一些其他的方法來使用ES6將這種功能帶到React組件中。 其中一種如下:

classFooextendsReact.Component{constructor(props){super(props);this.shouldComponentUpdate=React.addons.PureRenderMixin.shouldComponentUpdate.bind(this);}render(){return

Helllo

}}

小結

高階組件非常的強大并且表達能力強。目前,它們使用非常廣泛,并且可以作為古老的mixin語言的替代。

對于高階組件的使用最出名的要屬Relay框架。Relay是Facebook發布的一個完全的基于React的框架。 你所編寫的沒一個組件都可以被包裹進Relay容器,它能夠自動檢索數據依賴,以及一些其他的事。 這非常的便捷,并且在你剛接觸的時候會覺得很神奇。

References

About mixins in ES6 in official React blog

Mixins Are Dead. Long Live Composition by Dan Abramov

JSX Spread Attributes

Gist with PureRenderMixin in ES6

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內容