国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

leap_frog / 3443人閱讀

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

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

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

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

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

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

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

本文檔和他的演講都是對實際代碼庫的簡化,因此你可以通過熟悉它們來獲得更好的理解。

概述

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

掛載(mounting)作為遞歸過程

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

ReactDOM.render(, rootEl);

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

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

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

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

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

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

這個過程是遞歸的。App可能會渲染,可能會渲染

),都沒有關(guān)系,都會去讓渲染器去負責mounting它。

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

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

如果我們要擴展代碼來處理計算機元素,它將如下所示:

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

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

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

介紹內(nèi)部實例

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

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

但是,我們上面的實現(xiàn)只知道如何掛載初始樹。它無法對其執(zhí)行更新,因為它不存儲所有必需的信息,例如所有publicInstances,或哪些DOM節(jié)點對應于哪些組件。

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

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

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

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

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

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

  getPublicInstance() {
    // 對于復合的組件,暴露類的實例
    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ù)元素實例化子內(nèi)部實例
    // 他將是DOMComponent,例如
,

// 或者是CompositeComponent,例如

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

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

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

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

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

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)建并保存包含的子元素
    // 這些子元素,每個都可以是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é)點作為mount的節(jié)點返回
    return node;
  }
}

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

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

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

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

相關(guān)文章

  • react進階漫談

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

    neuSnail 評論0 收藏0
  • react進階漫談

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

    wyk1184 評論0 收藏0
  • react進階漫談

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

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

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

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

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

    dailybird 評論0 收藏0

發(fā)表評論

0條評論

leap_frog

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<