React高階組件

React高階組件

在開始聊高階組件之前我們先來看下高階函數(shù)和高階組件在形式上的差異:

一换薄、什么是裝飾器模式:

要想正確理解設(shè)計模式,首先必須明確它是為了解決什么問題而提出來的植锉。

那裝飾器模式到底是為了解決什么問題呢啥酱?在我們的開發(fā)過程中我們會為了一些通用功能在多個不同的組件、接口或者類中使用竖般,這個時候我們這些功能寫到每個組件咒唆、接口或者類中届垫,但是這樣非常不利于維護。

裝飾器就是為了解決在不修改原本組件全释、接口或者類的時候為其添加額外的功能装处。

從本質(zhì)上看裝飾器模式是一個包裝模式((Wrapper Pattern),它是通過封裝其他對象達到設(shè)計的目的的浸船。

react的高階組件本質(zhì)也是裝飾器模式妄迁,以后會有一篇文章會專門詳解react的高階組件。

理解了裝飾器的能解決了什么問題李命,那我們一遍在什么情況下考慮使用裝飾器模式呢登淘?我的理解是:

  • 需要擴展一個類,為這個類附加一個方法或者屬性的時候封字;
  • 需要修改一個類的功能黔州,或者重構(gòu)這個類中的某個方法耍鬓;

二、裝飾器的基本概念:

上面我們解釋了什么是裝飾器模式流妻,下面我們將要ES7的裝飾器的一些基本概念:如何定義裝飾器牲蜀、裝飾器執(zhí)行時機、裝飾器類型绅这。

1涣达、如何定義裝飾器

裝飾器本質(zhì)是一個函數(shù),可以分為帶參數(shù)和不帶參數(shù)(也叫裝飾器工廠)证薇,裝飾器使用 @expression這種形式度苔,expression求值后必須為一個函數(shù),它會在運行時被調(diào)用浑度,被裝飾的聲明信息做為參數(shù)傳入林螃。

@Test()
class Hello {}

function Test(target:any) {
    console.log("I am decorator.")
}

2、裝飾器執(zhí)行時機

修飾器對類的行為的改變俺泣,是代碼編譯時發(fā)生的(不是TypeScript編譯,而是js在執(zhí)行機中編譯階段)完残,而不是在運行時伏钠。這意味著,修飾器能在編譯階段運行代碼谨设。也就是說熟掂,修飾器本質(zhì)就是編譯時執(zhí)行的函數(shù)

3、裝飾器的類型

類裝飾器扎拣、屬性裝飾器赴肚、方法裝飾器、參數(shù)裝飾器

三二蓝、裝飾器類型:

  • 類修飾器

類裝飾器一般主要應(yīng)用于類構(gòu)造函數(shù)誉券,可以監(jiān)視、修改刊愚、替換類的定義踊跟,裝飾器用來裝飾類的時候。裝飾器函數(shù)的第一個參數(shù)鸥诽,就是所要裝飾的目標類本身商玫。

a、添加靜態(tài)屬性或方法

@Test()
class Hello {}

function Test(target) {
   target.a = 1;
}

let o = new Hello();

console.log(o.a) ==>1

b牡借、添加實例屬性或方法

@Test()
class Hello {}

function Test(target) {
   target.prototype.a = 1;
   target.prototype.f = function(){
       console.log("新增加方法")
   };

}

let o = new Hello();
o.f() ==>"新增加方法"
console.log(o.a) ==>1

c拳昌、裝飾器工廠(函數(shù)柯里化)

很多文章說裝飾器工廠是閉包,其實不準確钠龙,關(guān)于高階函數(shù)炬藤、閉包御铃、函數(shù)柯里化可以參考:
理解運用JS的閉包、高階函數(shù)刻像、柯里化

@Test('hello')
class Hello {}

function Test(str) {
   return function(){
        target.prototype.a = str;
        target.prototype.f = function(){
            console.log(str)
        };
   }

}

let o = new Hello();
o.f() ==>"hello"
console.log(o.a) ==>"hello"

d畅买、重載構(gòu)造函數(shù)

@Test('hello')
class Hello {
    constructor(){
        this.a= 1
    }
    f(){
         console.log('我是原始方法',this.a)
    }

}

function Test(target) {
  return class extends target{
      f(){
         console.log('我是裝飾器方法',this.a)
    }
  }

}

let o = new Hello();
o.f() ==>"我是裝飾器方法",1
  • 方法裝飾器

它會被應(yīng)用到方法的 屬性描述符上,可以用來監(jiān)視细睡,修改或者替換方法定義谷羞。
方法裝飾會在運行時傳入下列3個參數(shù):

  1. target:對于靜態(tài)成員來說是類的構(gòu)造函數(shù),對于實例成員是類的原型對象溜徙。
  2. key: 成員的名字湃缎。
  3. descriptor:成員的屬性描述符。
descriptor:
// {
//   value: specifiedFunction,
//   enumerable: false,
//   configurable: true,
//   writable: true
// };

方法裝飾器最后必須返回descriptor

function nameDecorator(target, key, descriptor) {
    descriptor.value = () => {
        return 'jake';
    }
    return descriptor;
}

class Person {
    constructor() {
        this.name = 'jake'
    }
    @nameDecorator
    getName() {
        return this.name;
    }
}

let p1 = new Person();
console.log(p1.getName())



另外一個經(jīng)典例子

class Math {
  @log
  add(a, b) {
    return a + b;
  }
}

function log(target, name, descriptor) {
  var oldValue = descriptor.value;

  descriptor.value = function(...list) {
    console.log(list);
    console.log(`Calling ${name} with`, ...list);
    return oldValue.call(this, ...list);
  };

  return descriptor;
}

const math = new Math();

// passed parameters should get logged now
let result = math.add(2, 4);

console.log(result)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蠢壹,一起剝皮案震驚了整個濱河市嗓违,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌图贸,老刑警劉巖蹂季,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異疏日,居然都是意外死亡偿洁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門沟优,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涕滋,“玉大人,你說我怎么就攤上這事挠阁”龇危” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵侵俗,是天一觀的道長锨用。 經(jīng)常有香客問我,道長隘谣,這世上最難降的妖魔是什么黔酥? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮洪橘,結(jié)果婚禮上跪者,老公的妹妹穿的比我還像新娘。我一直安慰自己熄求,他們只是感情好渣玲,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著弟晚,像睡著了一般忘衍。 火紅的嫁衣襯著肌膚如雪逾苫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天枚钓,我揣著相機與錄音铅搓,去河邊找鬼。 笑死搀捷,一個胖子當著我的面吹牛星掰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嫩舟,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼氢烘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了家厌?” 一聲冷哼從身側(cè)響起播玖,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎饭于,沒想到半個月后蜀踏,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡掰吕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年脓斩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片畴栖。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖八千,靈堂內(nèi)的尸體忽然破棺而出吗讶,到底是詐尸還是另有隱情,我是刑警寧澤恋捆,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布照皆,位于F島的核電站,受9級特大地震影響沸停,放射性物質(zhì)發(fā)生泄漏膜毁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一愤钾、第九天 我趴在偏房一處隱蔽的房頂上張望瘟滨。 院中可真熱鬧,春花似錦能颁、人聲如沸杂瘸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽败玉。三九已至敌土,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間运翼,已是汗流浹背返干。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留血淌,地道東北人矩欠。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像六剥,于是被迫代替她去往敵國和親晚顷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 1. Decorator基本知識 在很多框架和庫中看到它的身影疗疟,尤其是React和Redux该默,還有mobx中,那什...
    cbw100閱讀 1,038評論 1 7
  • 前段時間在工作中寫Hybrid頁面時遇到了這樣的一個場景策彤,公司需要一系列的活動組件栓袖,在每個組件注冊的時候都需要調(diào)用...
    呆頭呆腦丶閱讀 2,060評論 1 18
  • 高階組件(HOC)是 React 中用于復(fù)用組件邏輯的一種高級技巧。HOC 自身不是 React API 的一部分...
    明里人閱讀 587評論 0 1
  • 高階組件是react應(yīng)用中很重要的一部分店诗,最大的特點就是重用組件邏輯裹刮。它并不是由React API定義出來的功能,...
    叫我蘇軾好嗎閱讀 899評論 0 0
  • React進階之高階組件 前言 本文代碼淺顯易懂庞瘸,思想深入實用捧弃。此屬于react進階用法,如果你還不了解react...
    流動碼文閱讀 1,184評論 0 1