Component和 PureComponent對比

React.Component和 React.PureComponent

在開發(fā)的時(shí)候,偶然看到別人的代碼使用了 React.PureComponent進(jìn)行繼承徘郭,我也跟著復(fù)制粘貼来庭,但是并不知道他到底有什么作用妒蔚,于是下來去了解了一下他兩的區(qū)別,總結(jié)一下月弛。
PureComponent使用淺比較的方式對比props和state肴盏,實(shí)現(xiàn)了shouldComponentUpdate()函數(shù),在某些情況下帽衙,使用PureComponent可以減少render函數(shù)的執(zhí)行菜皂,提升性能。

  • 組件繼承component:
export default class Page extends React.Component{
  constructor(props) {
    super(props);
    this.state = {
      isShow:false,
    };
    console.log('1');
  }
  componentDidUpdate() {
    console.log("componentDidUpdate")
  }

  @Bind()
  onClick() {
    this.setState({
      isShow: true,
    });
  };
  render() {
    console.log('2');
    return (
      <div>
        <button onClick={this.onClick}>點(diǎn)擊</button>
        <div>
         {this.state.isShow.toString()}
        </div>
      </div>
    );
  }
}

在首次渲染頁面的時(shí)候厉萝,依次打踊衅:'1', '2',當(dāng)?shù)谝淮吸c(diǎn)擊按鈕之后,打印'2', 'componentDidUpdate',在每次點(diǎn)擊按鈕之后谴垫,都會(huì)打印'2', 'componentDidUpdate'章母,說明每點(diǎn)擊一次,雖然state中的值沒有改變翩剪,都會(huì)調(diào)用render()和componentDidUpdate()方法乳怎,觸發(fā)頁面的重新渲染,通常情況下需要我們重新手動(dòng)調(diào)用shouldComponentUpdate()來判斷state的值是否有改變前弯,來決定頁面是否重新渲染舞肆。
因此,繼承自Component中的組件shouldComponentUpdate()默認(rèn)情況下總是返回true博杖,總是會(huì)觸發(fā)頁面的重新渲染椿胯。

  • 組件繼承pureComponent:
export default class Page extends React.PureComponent{
  constructor(props) {
    super(props);
    this.state = {
      isShow:false,
    };
    console.log('1');
  }
  componentDidUpdate() {
    console.log("componentDidUpdate")
  }

  @Bind()
  onClick() {
    this.setState({
      isShow: true,
    });
  };
  render() {
    console.log('2');
    return (
      <div>
        <button onClick={this.onClick}>點(diǎn)擊</button>
        <div>
         {this.state.isShow.toString()}
        </div>
      </div>
    );
  }
}

在首次渲染頁面的時(shí)候,依次打犹旮:'1', '2',當(dāng)?shù)谝淮吸c(diǎn)擊按鈕之后哩盲,打印'2', 'componentDidUpdate',在每次點(diǎn)擊按鈕之后,沒有輸出。在purComponent源碼中:

  // 這個(gè)變量用來控制組件是否需要更新
  var shouldUpdate = true;
  // inst 是組件實(shí)例
  if (inst.shouldComponentUpdate) {
    shouldUpdate = inst.shouldComponentUpdate(nextProps, nextState, nextContext);
  } else {
    if (this._compositeType === CompositeType.PureClass) {
      shouldUpdate = !shallowEqual(prevProps, nextProps) ||
        !shallowEqual(inst.state, nextState);
    }
  }

判斷新舊屬性和狀態(tài)是否相等廉油,是否需要重新渲染子組件惠险,減少render()方法的觸發(fā),節(jié)省了在虛擬DOM生成與對比的過程抒线,性能得到提升班巩。
PureComponent默認(rèn)實(shí)現(xiàn)的shouldComponentUpdate()方法使用的是淺比較:即值的比較或引用的比較, 不會(huì)進(jìn)行深層次的對比,所以當(dāng)props或state的值是引用類型時(shí)嘶炭,即使對象的值改變了抱慌,但是對象的引用沒變。

export default class Page extends React.PureComponent{
  constructor(props) {
    super(props);
    this.state = {
      isShow: [1,2],
    };
    console.log('1');
  }
  componentDidUpdate() {
    console.log("componentDidUpdate")
  }

  @Bind()
  onClick() {
    const { isShow } = this.state;
    isShow.push(1);
    this.setState({
      isShow,
    });
    console.log(this.state.isShow);
  };
  render() {
    console.log(this.state.isShow);
    return (
      <div>
        <button onClick={this.onClick}>點(diǎn)擊</button>
        {
           arr.map(item => <span key={item}>{item}</span>)
        }
      </div>
    );
  }
}

在上面這段代碼中眨猎,初次渲染打印'1',[1,2],點(diǎn)擊按鈕之后抑进,打印出[1,2],render()函數(shù)沒有執(zhí)行睡陪,頁面上展示的只有1 2寺渗。

總結(jié)

  1. PureComponent已經(jīng)用淺層對比props、state的方式替我們實(shí)現(xiàn)了shouldComponentUpdate()兰迫, 不僅能影響自身信殊,還會(huì)影響其子組件;
  2. PureComponent 某些情況下(props或state的值不經(jīng)常變動(dòng)汁果, 因?yàn)闇\比較也會(huì)耗時(shí))可以提升性能涡拘;

遺留問題

PureComponent只是進(jìn)行淺比較,無法判斷復(fù)雜數(shù)據(jù)類型(引用類型)的變化须鼎,還需要下來進(jìn)行深入的研究鲸伴。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末府蔗,一起剝皮案震驚了整個(gè)濱河市晋控,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌姓赤,老刑警劉巖赡译,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異不铆,居然都是意外死亡蝌焚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門誓斥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來只洒,“玉大人,你說我怎么就攤上這事劳坑”锨矗” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長涝开。 經(jīng)常有香客問我循帐,道長,這世上最難降的妖魔是什么舀武? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任拄养,我火速辦了婚禮,結(jié)果婚禮上银舱,老公的妹妹穿的比我還像新娘瘪匿。我一直安慰自己,他們只是感情好纵朋,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布柿顶。 她就那樣靜靜地躺著,像睡著了一般操软。 火紅的嫁衣襯著肌膚如雪嘁锯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天聂薪,我揣著相機(jī)與錄音家乘,去河邊找鬼。 笑死藏澳,一個(gè)胖子當(dāng)著我的面吹牛仁锯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播翔悠,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼业崖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蓄愁?” 一聲冷哼從身側(cè)響起双炕,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎撮抓,沒想到半個(gè)月后妇斤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡丹拯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年站超,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片乖酬。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡死相,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出咬像,到底是詐尸還是另有隱情算撮,我是刑警寧澤双肤,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站钮惠,受9級(jí)特大地震影響茅糜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜素挽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一蔑赘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧预明,春花似錦缩赛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至阅酪,卻和暖如春旨袒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背术辐。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工砚尽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人辉词。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓必孤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親瑞躺。 傳聞我的和親對象是個(gè)殘疾皇子敷搪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

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