成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

React PureComponent 源碼解析

ZHAO_ / 575人閱讀

摘要:自身的源碼也很簡(jiǎn)單,節(jié)選如下上面的就是暴露給外部使用的。關(guān)于的源碼分析就到這里。這是內(nèi)部使用的一個(gè)工具集。不過(guò)也不是萬(wàn)能的,特定情況下自己實(shí)現(xiàn)可能更高效。

TL;DR

React 15.3.0 新增了一個(gè) PureComponent 類(lèi),以 ES2015 class 的方式方便地定義純組件 (pure component)。這篇文章分析了一下源碼實(shí)現(xiàn),并衍生探討了下 shallowComparePureRenderMixin。相關(guān)的 GitHub PR 在 這里 。

PureComponent 源碼分析

這個(gè)類(lèi)的用法很簡(jiǎn)單,如果你有些組件是純組件,那么把繼承類(lèi)從 Component 換成 PureComponent 即可。當(dāng)組件更新時(shí),如果組件的 propsstate 都沒(méi)發(fā)生改變,render 方法就不會(huì)觸發(fā),省去 Virtual DOM 的生成和比對(duì)過(guò)程,達(dá)到提升性能的目的。

import React, { PureComponent } from "react"

class Example extends PureComponent {
  render() {
    // ...
  }
}

PureComponent 自身的源碼也很簡(jiǎn)單,節(jié)選如下:

function ReactPureComponent(props, context, updater) {
  // Duplicated from ReactComponent.
  this.props = props;
  this.context = context;
  this.refs = emptyObject;
  // We initialize the default updater but the real one gets injected by the
  // renderer.
  this.updater = updater || ReactNoopUpdateQueue;
}

function ComponentDummy() {}
ComponentDummy.prototype = ReactComponent.prototype;
ReactPureComponent.prototype = new ComponentDummy();
ReactPureComponent.prototype.constructor = ReactPureComponent;
// Avoid an extra prototype jump for these methods.
Object.assign(ReactPureComponent.prototype, ReactComponent.prototype);
ReactPureComponent.prototype.isPureReactComponent = true;

上面的 ReactPureComponent 就是暴露給外部使用的 PureComponent ??梢钥吹剿皇抢^承了 ReactComponent 再設(shè)定了一下 isPureReactComponent 屬性。ComponentDummy 是典型的 JavaScript 原型模擬繼承的做法,對(duì)此有疑惑的可以看 我的另一篇文章 。另外,為了避免原型鏈拉長(zhǎng)導(dǎo)致方法查找的性能開(kāi)銷(xiāo),還用 Object.assign 把方法從 ReactComponent 拷貝過(guò)來(lái)了。

PureRenderMixin 不一樣的是,這里完全沒(méi)有實(shí)現(xiàn) shouldComponentUpdate。那 PureComponent 的 props/state 比對(duì)是在哪里做的呢?答案是 ReactCompositeComponent。

ReactCompositeComponent 這個(gè)類(lèi)的信息太少,我只能推測(cè)它是負(fù)責(zé)實(shí)際渲染并維護(hù)組件實(shí)例的對(duì)象。建議大家從高層次了解 React 對(duì)組件的更新機(jī)制即可。以下幾篇官方文檔看完就足夠了。

Advanced Performance

Reconciliation

React (Virtual) DOM Terminology

這個(gè)類(lèi)的代碼改動(dòng)很多,但關(guān)鍵就在 這里 。下面是我簡(jiǎn)化后的代碼片段:

// 定義 CompositeTypes
var CompositeTypes = {
  ImpureClass: 0,         // 繼承自 Component 的組件
  PureClass: 1,           // 繼承自 PureComponent 的組件
  StatelessFunctional: 2, // 函數(shù)組件
};

// 省略一堆代碼,因?yàn)榧尤肓?CompositeTypes 造成的調(diào)整

// 這個(gè)變量用來(lái)控制組件是否需要更新
var shouldUpdate = true;

// inst 是組件實(shí)例
if (inst.shouldComponentUpdate) {
  shouldUpdate = inst.shouldComponentUpdate(nextProps, nextState, nextContext);
} else {
  if (this._compositeType === CompositeType.PureClass) {
    // 用 shallowEqual 對(duì)比 props 和 state 的改動(dòng)
    // 如果都沒(méi)改變就不用更新
    shouldUpdate =
      !shallowEqual(prevProps, nextProps) ||
      !shallowEqual(inst.state, nextState);
  }
}

簡(jiǎn)而言之,ReactCompositeComponent 會(huì)在 mount 的時(shí)候判斷各個(gè)組件的類(lèi)型,設(shè)定 _compositeType ,然后根據(jù)這個(gè)類(lèi)型來(lái)判斷是非需要更新組件。這個(gè) PR 中大部分改動(dòng)都是 因?yàn)榧恿?CompositeTypes 而做的調(diào)整性工作,實(shí)際跟 PureComponent 有關(guān)的就是 shallowEqual 的那兩行。

關(guān)于 PureComponent 的源碼分析就到這里。其他的就都是細(xì)節(jié)和測(cè)試,有興趣的可以自己看看 PR 。

shallowEqual, shallowCompare, PureRenderMixin 的聯(lián)系

我們知道在 PureComponent 出現(xiàn)之前,shallowComparePureRenderMixin 都可以做一樣的事情。于是好奇看了一下后兩者的代碼。

shallowCompare 的源碼:

var shallowEqual = require("shallowEqual");

function shallowCompare(instance, nextProps, nextState) {
  return (
    !shallowEqual(instance.props, nextProps) ||
    !shallowEqual(instance.state, nextState)
  );
}

module.exports = shallowCompare;

PureRenderMixin 的源碼:

var shallowCompare = require("shallowCompare");

var ReactComponentWithPureRenderMixin = {
  shouldComponentUpdate: function(nextProps, nextState) {
    return shallowCompare(this, nextProps, nextState);
  },
};

module.exports = ReactComponentWithPureRenderMixin;

可以看到,shallowCompare 依賴(lài) shallowEqual ,做的是跟剛才在 ReactCompositeComponent 里一樣的事情 -- 對(duì)比 props 和 state 。這個(gè)工具函數(shù)一般配合組件的 shouldComponentUpdate 一起使用,而這就是 PureRenderMixin 做的事情。不過(guò) PureRenderMixin 是配合 React.createClass 這種老的組件定義方式使用的,在 ES2015 class 里用起來(lái)不是很方便,這也是 PureComponent 誕生的原因之一。

最后 shallowEqual 這玩意定義在哪里呢?它其實(shí)不是 React 的一部分,而是 fbjs 的一部分。這是 Facebook 內(nèi)部使用的一個(gè)工具集。

小結(jié)

React 之前一直沒(méi)有針對(duì) ES2015 class 的純組件寫(xiě)法,雖然自己實(shí)現(xiàn)起來(lái)并不麻煩,但這也算給出了一個(gè)官方的解決方案,可以不再依賴(lài) addon 了。不過(guò) PureComponent 也不是萬(wàn)能的,特定情況下自己實(shí)現(xiàn) shouldComponentUpdate 可能更高效。

參考資料

PureComponent PR
shallowEqual
Shallow Compare
PureRenderMixin

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/80199.html

相關(guān)文章

  • Component,PureComponent源碼解析

    摘要:首先是創(chuàng)建了一個(gè)構(gòu)造函數(shù),他的原型指到的原型然后創(chuàng)建了一個(gè)加上了和一樣的屬性這里為啥不用。的原型指向的實(shí)例修改原型的屬性使其正確指向的構(gòu)造函數(shù),并掛一個(gè)的屬性。 每次都信誓旦旦的給自己立下要好好學(xué)習(xí)react源碼的flag,結(jié)果都是因?yàn)槟硞€(gè)地方卡住了,或是其他原因沒(méi)看多少就放棄了。這次又給自己立個(gè)flag-堅(jiān)持看完react源碼。為了敦促自己,特開(kāi)設(shè)這樣一個(gè)專(zhuān)欄來(lái)記錄自己的學(xué)習(xí)歷程,這...

    luqiuwen 評(píng)論0 收藏0
  • React源碼解析React.Component()/PureComponent()

    摘要:只涉及了,其他均沒(méi)有自己實(shí)現(xiàn)。這種組件的復(fù)用性是最強(qiáng)的。所以會(huì)新建,只繼承的原型,不包括,以此來(lái)節(jié)省內(nèi)存。 showImg(https://segmentfault.com/img/remote/1460000019783989); 一、React.Component() GitHub:https://github.com/AttackXiaoJinJin/reactExplain/...

    Cristalven 評(píng)論0 收藏0
  • 基于React版本16.4的源碼解析(一)

    摘要:本次分析的源碼采用的是的版本核心接口提供了處理的工具集我們先來(lái)看看做了什么事情即當(dāng)為空時(shí),返回不為時(shí)調(diào)用,最終返回一個(gè)數(shù)組這里說(shuō)一下,可以通過(guò)傳入的對(duì)所有子組件進(jìn)行操作,具體使用方法看下圖參數(shù)通過(guò)配合的例子把父組件的賦值給每個(gè)子組件我們先不 本次分析的源碼采用的是16.4.1的版本 核心接口 showImg(https://segmentfault.com/img/bVbeT9f?w=...

    joywek 評(píng)論0 收藏0
  • 如何優(yōu)化你的超大型React應(yīng)用 【原創(chuàng)精讀】

    摘要:往往純的單頁(yè)面應(yīng)用一般不會(huì)太復(fù)雜,所以這里不引入和等等,在后面復(fù)雜的跨平臺(tái)應(yīng)用中我會(huì)將那些技術(shù)一擁而上。構(gòu)建極度復(fù)雜,超大數(shù)據(jù)的應(yīng)用。 showImg(https://segmentfault.com/img/bVbvphv?w=1328&h=768); React為了大型應(yīng)用而生,Electron和React-native賦予了它構(gòu)建移動(dòng)端跨平臺(tái)App和桌面應(yīng)用的能力,Taro則賦...

    cfanr 評(píng)論0 收藏0
  • 如何優(yōu)化你的超大型React應(yīng)用 【原創(chuàng)精讀】

    摘要:往往純的單頁(yè)面應(yīng)用一般不會(huì)太復(fù)雜,所以這里不引入和等等,在后面復(fù)雜的跨平臺(tái)應(yīng)用中我會(huì)將那些技術(shù)一擁而上。構(gòu)建極度復(fù)雜,超大數(shù)據(jù)的應(yīng)用。 showImg(https://segmentfault.com/img/bVbvphv?w=1328&h=768); React為了大型應(yīng)用而生,Electron和React-native賦予了它構(gòu)建移動(dòng)端跨平臺(tái)App和桌面應(yīng)用的能力,Taro則賦...

    codecook 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

ZHAO_

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<