成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

從代碼實(shí)踐潛入React內(nèi)部,深入diff

leap_frog / 3498人閱讀

摘要:概述協(xié)調(diào),調(diào)解本身不存在公共的。安裝的確切結(jié)果有時(shí)在源代碼中稱為取決于渲染器,可以是節(jié)點(diǎn),字符串或表示原生視圖。關(guān)鍵的缺失部分是對(duì)更新的支持。為避免混淆,我們將和的實(shí)例叫做內(nèi)部實(shí)例。但是,內(nèi)部實(shí)例樹包含復(fù)合和主機(jī)內(nèi)部實(shí)例。

本節(jié)是 stack reconciler程序的實(shí)現(xiàn)說(shuō)明的集合。

本文有一定的技術(shù)含量,要對(duì)React公共API以及它如何分為核心,渲染器和協(xié)調(diào)(和解,reconciler)程序有很深的理解。如果你對(duì)React代碼庫(kù)不是很熟悉,請(qǐng)首先閱讀代碼庫(kù)概述。

它還假設(shè)你了解React組件的實(shí)例和元素之間的差異。

stack reconciler用于15版本和早期. 它的代碼在 src/renderers/shared/stack/reconciler.

視頻:從頭開始構(gòu)建React

Paul O’Shannessy談到了從頭開始構(gòu)建react,這在很大程度上啟發(fā)了這個(gè)文檔。

本文檔和他的演講都是對(duì)實(shí)際代碼庫(kù)的簡(jiǎn)化,因此你可以通過(guò)熟悉它們來(lái)獲得更好的理解。

概述

reconciler(協(xié)調(diào),調(diào)解)本身不存在公共的API。像React DOM和React Native這樣的渲染器使用它根據(jù)用戶編寫的React組件有效地更新用戶界面。

掛載(mounting)作為遞歸過(guò)程

讓我們考慮第一次掛載組件:

ReactDOM.render(, rootEl);

React DOM會(huì)將傳遞給調(diào)節(jié)器(reconciler)。請(qǐng)記住,是一個(gè)React元素,即對(duì)要呈現(xiàn)的內(nèi)容的描述。你可以將其視為普通對(duì)象(筆者:不了解的可以查看這篇文章):

console.log();
// { type: App, props: {} }

調(diào)解器會(huì)檢查這個(gè)App是類還是函數(shù)(對(duì)于這個(gè)得實(shí)現(xiàn)可以查看如何知道是函數(shù)還是類這篇文章)。

如果App是一個(gè)函數(shù),則調(diào)解器將調(diào)用App(props)來(lái)獲取渲染元素。

如果App是一個(gè)類,那么調(diào)解器會(huì)通過(guò)new App(props)去實(shí)例化App,調(diào)用componentWillMount生命周期方法,然后調(diào)用render方法來(lái)獲取渲染的元素。

無(wú)論哪種方式,調(diào)解器都將得知App“渲染到”的元素。

這個(gè)過(guò)程是遞歸的。App可能會(huì)渲染,可能會(huì)渲染

),都沒(méi)有關(guān)系,都會(huì)去讓渲染器去負(fù)責(zé)mounting它。

由子組件生成的DOM節(jié)點(diǎn)將附加到父DOM節(jié)點(diǎn),并且將遞歸地組裝完整的DOM結(jié)構(gòu)。

注意: 調(diào)解器本身與DOM無(wú)關(guān)。mounting(安裝)的確切結(jié)果(有時(shí)在源代碼中稱為“mount image”)取決于渲染器,可以是DOM節(jié)點(diǎn)(React DOM),字符串(React DOM Server)或表示原生視圖(React Native)。

如果我們要擴(kuò)展代碼來(lái)處理計(jì)算機(jī)元素,它將如下所示:

function isClass(type) {
  // 繼承自 React.Component 類有一個(gè)標(biāo)簽 isReactComponent
  return (
    Boolean(type.prototype) &&
    Boolean(type.prototype.isReactComponent)
  );
}

// 這個(gè)函數(shù)只處理復(fù)合的元素
// 比如像是, 

這是有效的,但仍遠(yuǎn)未達(dá)到協(xié)調(diào)者的實(shí)際運(yùn)行方式。關(guān)鍵的缺失部分是對(duì)更新的支持。

介紹內(nèi)部實(shí)例

react的關(guān)鍵特點(diǎn)是你可以重新渲染所有東西,它不會(huì)重新創(chuàng)建DOM或重置狀態(tài)。

ReactDOM.render(, rootEl);
// 應(yīng)該重用現(xiàn)有的DOM:
ReactDOM.render(, rootEl);

但是,我們上面的實(shí)現(xiàn)只知道如何掛載初始樹。它無(wú)法對(duì)其執(zhí)行更新,因?yàn)樗淮鎯?chǔ)所有必需的信息,例如所有publicInstances,或哪些DOM節(jié)點(diǎn)對(duì)應(yīng)于哪些組件。

堆棧協(xié)調(diào)器代碼庫(kù)通過(guò)使mount函數(shù)成為一個(gè)類上面的方法來(lái)解決這個(gè)問(wèn)題。但是這種方法存在一些缺點(diǎn),我們?cè)谡谶M(jìn)行的協(xié)調(diào)重寫任務(wù)中正朝著相反的方向去發(fā)展(筆者:目前fiber已經(jīng)出來(lái)了)。不過(guò) 這就是它現(xiàn)在的運(yùn)作方式。

我們將創(chuàng)建兩個(gè)類:DOMComponentCompositeComponent,而不是多帶帶的mountHostmountComposite函數(shù)。

兩個(gè)類都有一個(gè)接受元素的構(gòu)造函數(shù),以及一個(gè)返回已安裝節(jié)點(diǎn)的mount()方法。我們將用實(shí)例化類的工廠替換頂級(jí)mount()函數(shù):

function instantiateComponent(element) {
  var type = element.type;
  if (typeof type === "function") {
    // 用戶定義的組件
    return new CompositeComponent(element);
  } else if (typeof type === "string") {
    // 特定于平臺(tái)的組件,如計(jì)算機(jī)組件(
) return new DOMComponent(element); } }

首先,讓我們考慮下CompositeComponent的實(shí)現(xiàn):

class CompositeComponent {
  constructor(element) {
    this.currentElement = element;
    this.renderedComponent = null;
    this.publicInstance = null;
  }

  getPublicInstance() {
    // 對(duì)于復(fù)合的組件,暴露類的實(shí)例
    return this.publicInstance;
  }

  mount() {
    var element = this.currentElement;
    var type = element.type;
    var props = element.props;

    var publicInstance;
    var renderedElement;
    if (isClass(type)) {
      // Component class
      publicInstance = new type(props);
      // Set the props
      publicInstance.props = props;
      // Call the lifecycle if necessary
      if (publicInstance.componentWillMount) {
        publicInstance.componentWillMount();
      }
      renderedElement = publicInstance.render();
    } else if (typeof type === "function") {
      // Component function
      publicInstance = null;
      renderedElement = type(props);
    }

    // Save the public instance
    this.publicInstance = publicInstance;

    // 根據(jù)元素實(shí)例化子內(nèi)部實(shí)例
    // 他將是DOMComponent,例如
,

// 或者是CompositeComponent,例如,

這與我們之前的mountComposite()實(shí)現(xiàn)沒(méi)什么不同,但現(xiàn)在我們可以存儲(chǔ)一些信息,例如this.currentElement,this.renderedComponentthis.publicInstance,在更新期間使用。

請(qǐng)注意,CompositeComponent的實(shí)例與用戶提供的element.type的實(shí)例不同。CompositeComponent是我們的協(xié)調(diào)程序的實(shí)現(xiàn)細(xì)節(jié),永遠(yuǎn)不會(huì)向用戶公開。用戶定義的類是我們從element.type讀取的,CompositeComponent會(huì)創(chuàng)建這個(gè)類的實(shí)例。

為避免混淆,我們將CompositeComponentDOMComponent的實(shí)例叫做“內(nèi)部實(shí)例”。 它們存在,因此我們可以將一些長(zhǎng)期存在的數(shù)據(jù)與它們相關(guān)聯(lián)。只有渲染器和調(diào)解器知道它們存在。

相反,我們將用戶定義類的實(shí)例稱為“公共實(shí)例(public instance)”。 公共實(shí)例是你在render()和組件其他的方法中看到的this.

至于mountHost()方法,重構(gòu)成了在DOMComponent類上的mount()方法,看起來(lái)像這樣:

class DOMComponent {
  constructor(element) {
    this.currentElement = element;
    this.renderedChildren = [];
    this.node = null;
  }

  getPublicInstance() {
    // For DOM components, only expose the DOM node.
    return this.node;
  }

  mount() {
    var element = this.currentElement;
    var type = element.type;
    var props = element.props;
    var children = props.children || [];
    if (!Array.isArray(children)) {
      children = [children];
    }

    // Create and save the node
    var node = document.createElement(type);
    this.node = node;

    // Set the attributes
    Object.keys(props).forEach(propName => {
      if (propName !== "children") {
        node.setAttribute(propName, props[propName]);
      }
    });

    // 創(chuàng)建并保存包含的子元素
    // 這些子元素,每個(gè)都可以是DOMComponent或CompositeComponent
    // 這些匹配是依賴于元素類型的返回值(string或function)
    var renderedChildren = children.map(instantiateComponent);
    this.renderedChildren = renderedChildren;

    // Collect DOM nodes they return on mount
    var childNodes = renderedChildren.map(child => child.mount());
    childNodes.forEach(childNode => node.appendChild(childNode));

    // DOM節(jié)點(diǎn)作為mount的節(jié)點(diǎn)返回
    return node;
  }
}

與上面的相比,mountHost()重構(gòu)之后的主要區(qū)別是現(xiàn)在將this.nodethis.renderedChildren與內(nèi)部DOM組件實(shí)例相關(guān)聯(lián)。我們會(huì)用他來(lái)用于在后面做非破壞性的更新。

因此,每個(gè)內(nèi)部實(shí)例(復(fù)合或主機(jī))現(xiàn)在都指向其子級(jí)內(nèi)部實(shí)例。為了幫助可視化,如果函數(shù)組件呈現(xiàn)

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/101075.html

相關(guān)文章

  • react進(jìn)階漫談

    摘要:父組件向子組件之間非常常見(jiàn),通過(guò)機(jī)制傳遞即可。我們應(yīng)該聽說(shuō)過(guò)高階函數(shù),這種函數(shù)接受函數(shù)作為輸入,或者是輸出一個(gè)函數(shù),比如以及等函數(shù)。在傳遞數(shù)據(jù)的時(shí)候,我們可以用進(jìn)一步提高性能。 本文主要談自己在react學(xué)習(xí)的過(guò)程中總結(jié)出來(lái)的一些經(jīng)驗(yàn)和資源,內(nèi)容邏輯參考了深入react技術(shù)棧一書以及網(wǎng)上的諸多資源,但也并非完全照抄,代碼基本都是自己實(shí)踐,主要為平時(shí)個(gè)人學(xué)習(xí)做一個(gè)總結(jié)和參考。 本文的關(guān)鍵...

    neuSnail 評(píng)論0 收藏0
  • react進(jìn)階漫談

    摘要:父組件向子組件之間非常常見(jiàn),通過(guò)機(jī)制傳遞即可。我們應(yīng)該聽說(shuō)過(guò)高階函數(shù),這種函數(shù)接受函數(shù)作為輸入,或者是輸出一個(gè)函數(shù),比如以及等函數(shù)。在傳遞數(shù)據(jù)的時(shí)候,我們可以用進(jìn)一步提高性能。 本文主要談自己在react學(xué)習(xí)的過(guò)程中總結(jié)出來(lái)的一些經(jīng)驗(yàn)和資源,內(nèi)容邏輯參考了深入react技術(shù)棧一書以及網(wǎng)上的諸多資源,但也并非完全照抄,代碼基本都是自己實(shí)踐,主要為平時(shí)個(gè)人學(xué)習(xí)做一個(gè)總結(jié)和參考。 本文的關(guān)鍵...

    wyk1184 評(píng)論0 收藏0
  • react進(jìn)階漫談

    摘要:父組件向子組件之間非常常見(jiàn),通過(guò)機(jī)制傳遞即可。我們應(yīng)該聽說(shuō)過(guò)高階函數(shù),這種函數(shù)接受函數(shù)作為輸入,或者是輸出一個(gè)函數(shù),比如以及等函數(shù)。在傳遞數(shù)據(jù)的時(shí)候,我們可以用進(jìn)一步提高性能。 本文主要談自己在react學(xué)習(xí)的過(guò)程中總結(jié)出來(lái)的一些經(jīng)驗(yàn)和資源,內(nèi)容邏輯參考了深入react技術(shù)棧一書以及網(wǎng)上的諸多資源,但也并非完全照抄,代碼基本都是自己實(shí)踐,主要為平時(shí)個(gè)人學(xué)習(xí)做一個(gè)總結(jié)和參考。 本文的關(guān)鍵...

    junnplus 評(píng)論0 收藏0
  • FE.SRC-React實(shí)戰(zhàn)與原理筆記

    摘要:異步實(shí)戰(zhàn)狀態(tài)管理與組件通信組件通信其他狀態(tài)管理當(dāng)需要改變應(yīng)用的狀態(tài)或有需要更新時(shí),你需要觸發(fā)一個(gè)把和載荷封裝成一個(gè)。的行為是同步的。所有的狀態(tài)變化必須通過(guò)通道。前端路由實(shí)現(xiàn)與源碼分析設(shè)計(jì)思想應(yīng)用是一個(gè)狀態(tài)機(jī),視圖與狀態(tài)是一一對(duì)應(yīng)的。 React實(shí)戰(zhàn)與原理筆記 概念與工具集 jsx語(yǔ)法糖;cli;state管理;jest單元測(cè)試; webpack-bundle-analyzer Sto...

    PumpkinDylan 評(píng)論0 收藏0
  • 2017文章總結(jié)

    摘要:歡迎來(lái)我的個(gè)人站點(diǎn)性能優(yōu)化其他優(yōu)化瀏覽器關(guān)鍵渲染路徑開啟性能優(yōu)化之旅高性能滾動(dòng)及頁(yè)面渲染優(yōu)化理論寫法對(duì)壓縮率的影響唯快不破應(yīng)用的個(gè)優(yōu)化步驟進(jìn)階鵝廠大神用直出實(shí)現(xiàn)網(wǎng)頁(yè)瞬開緩存網(wǎng)頁(yè)性能管理詳解寫給后端程序員的緩存原理介紹年底補(bǔ)課緩存機(jī)制優(yōu)化動(dòng) 歡迎來(lái)我的個(gè)人站點(diǎn) 性能優(yōu)化 其他 優(yōu)化瀏覽器關(guān)鍵渲染路徑 - 開啟性能優(yōu)化之旅 高性能滾動(dòng) scroll 及頁(yè)面渲染優(yōu)化 理論 | HTML寫法...

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

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

0條評(píng)論

閱讀需要支付1元查看
<