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

資訊專欄INFORMATION COLUMN

React Fiber源碼分析 第一篇

amc / 1240人閱讀

摘要:系列文章源碼分析第一篇源碼分析第二篇同步模式源碼分析第三篇異步狀態(tài)源碼分析第四篇歸納總結(jié)前言是在版本中的大更新,利用了閑余時間看了一些源碼,做個小記錄流程圖源碼分析先由編譯,調(diào)用,入?yún)?,打印出來可以看到,,分別代表著元素原生元素,回調(diào)函數(shù)

系列文章

React Fiber源碼分析 第一篇
React Fiber源碼分析 第二篇(同步模式)
React Fiber源碼分析 第三篇(異步狀態(tài))
React Fiber源碼分析 第四篇(歸納總結(jié))

前言

React Fiber是React在V16版本中的大更新,利用了閑余時間看了一些源碼,做個小記錄~

流程圖

源碼分析

先由babel編譯, 調(diào)用reactDOM.render,入?yún)?strong>element, container, callback, 打印出來可以看到element,container,callback分別代表著react元素、DOM原生元素,回調(diào)函數(shù)

1.render實際上調(diào)用的是legacyRenderSubtreeIntoContainer函數(shù)

render: function (element, container, callback) {
  return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
}

2.legacyRenderSubtreeIntoContainer 這個函數(shù), 實際上是初始化了root, 并調(diào)用了root.render方法, 而root是由legacyCreateRootFromDOMContainer函數(shù)返回的

function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
  var root = container._reactRootContainer;
  if (!root) {
    // 初始化root
    root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);// Initial mount should not be batched.
    unbatchedUpdates(function () {
      if (parentComponent != null) {
        root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
      } else {
        // 調(diào)用root的render方法
        root.render(children, callback);
      }
    });
  } else {
    ......
  }
}

3.從代碼中看出, legacyCreateRootFromDOMContainer執(zhí)行了兩個操作, 一個是清除掉所有的子元素, 另外一個則是返回了一個 ReactRoot實例, 這里需要注意一點, root默認(rèn)是同步更新的, 即isAsync 默認(rèn)為false

function legacyCreateRootFromDOMContainer(container, forceHydrate) {
  ...// 清除所有子元素
  if (!shouldHydrate) {
    var warned = false;
    var rootSibling = void 0;
    while (rootSibling = container.lastChild) {
      {
        if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
          warned = true;
        }
      }
      container.removeChild(rootSibling);
    }
  }// 默認(rèn)為同步狀態(tài)
  var isAsync = false;
  return new ReactRoot(container, isAsync, shouldHydrate);
}

4.從ReactRoot中, 我們把createContainer返回值賦給了 實例的_internalRoot, 往下看createContainer

function ReactRoot(container, isAsync, hydrate) {
  var root = createContainer(container, isAsync, hydrate);
  this._internalRoot = root;
}

5.從createContainer看出, createContainer實際上是直接返回了createFiberRoot, 而createFiberRoot則是通過createHostRootFiber函數(shù)的返回值uninitializedFiber,并將其賦值在root對象的current上, 這里需要注意一個點就是,uninitializedFiber的stateNode的值是root, 即他們互相引用

function createContainer(containerInfo, isAsync, hydrate) {
  return createFiberRoot(containerInfo, isAsync, hydrate);
}
function createFiberRoot(containerInfo, isAsync, hydrate) {
  // 創(chuàng)建hostRoot并賦值給uninitiallizedFiber
  var uninitializedFiber = createHostRootFiber(isAsync);
  // 互相引用
  var root = void 0;
  root = {
      current: uninitializedFiber,
      ...
  };
 uninitializedFiber.stateNode = root; 

6.最后是返回了一個fiberNode的實例, 在這里我們可以看到mode這個字段, 由于在一開始就將isAsync初始化為false, 所以mode實際上就代表了同步

在這里, 整理一下各個實例的關(guān)系,

root為ReactRoot實例

root._internalRoot 即為fiberRoot實例,

root._internalRoot.current即為Fiber實例,

root._internalRoot.current.stateNode = root._internalRoot

function createHostRootFiber(isAsync) {
  var mode = isAsync ? AsyncMode | StrictMode : NoContext;
  return createFiber(HostRoot, null, null, mode);
}
var createFiber = function (tag, pendingProps, key, mode) {
  return new FiberNode(tag, pendingProps, key, mode);
};
function FiberNode(tag, pendingProps, key, mode) {
  // Instance
  this.tag = tag;
  this.key = key;
  this.type = null;
  this.stateNode = null;

  // Fiber
  this.return = null;
  this.child = null;
  this.sibling = null;
  this.index = 0;

  ...
}

7.初始化完成, 接下來就是root.render執(zhí)行了, 在這里, 先暫時忽略ReactWork, 把work._onCommit當(dāng)成一個回調(diào)函數(shù)即可, 可以看到, root即FiberRoot實例被當(dāng)成參數(shù)傳入了updateContsainer里面, 往下看updateContainer

ReactRoot.prototype.render = function (children, callback) {
  var root = this._internalRoot;
  var work = new ReactWork();
  callback = callback === undefined ? null : callback;
  if (callback !== null) {
    work.then(callback);
  }
  updateContainer(children, root, null, work._onCommit);
  return work;
};

8.updateContsainer里面使用了 currentTimeexpirationTime,

currentTime是用來計算expirationTime,

expirationTime代表著優(yōu)先級, 留在后續(xù)分析,

這里我們知道是同步更新 即 expirationTime = 1. 緊接著調(diào)用了updateContainerAtExpirationTime

function updateContainer(element, container, parentComponent, callback) {
  var current$$1 = container.current;
  var currentTime = requestCurrentTime();
  var expirationTime = computeExpirationForFiber(currentTime, current$$1);
  return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
}

9.updateContainerAtExpirationTime將current(即Fiber實例)提取出來, 并作為參數(shù)傳入調(diào)用scheduleRootUpdate

function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
  // TODO: If this is a nested container, this won"t be the root.
  var current$$1 = container.current;
  ...
  return scheduleRootUpdate(current$$1, element, expirationTime, callback);
}

到了這里告一段落, scheduleRootUpdate接下來就是React新版本異步渲染的核心了, 留在下一篇繼續(xù)解讀

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

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

相關(guān)文章

  • React Fiber源碼分析 第四篇(歸納總結(jié))

    摘要:為什么網(wǎng)頁性能會變高要回答這個問題,需要回頭看是單線程的知識點。在分析的過程中,發(fā)現(xiàn)了的源碼中使用了很多鏈?zhǔn)浇Y(jié)構(gòu),回調(diào)鏈,任務(wù)鏈等,這個主要是為了增刪時性能比較高 系列文章 React Fiber源碼分析 第一篇 React Fiber源碼分析 第二篇(同步模式) React Fiber源碼分析 第三篇(異步狀態(tài)) React Fiber源碼分析 第四篇(歸納總結(jié)) 前言 Rea...

    jsdt 評論0 收藏0
  • React Fiber源碼分析 第三篇(異步狀態(tài))

    摘要:系列文章源碼分析第一篇源碼分析第二篇同步模式源碼分析第三篇異步狀態(tài)源碼分析第四篇歸納總結(jié)前言是在版本中的大更新,利用了閑余時間看了一些源碼,做個小記錄流程圖源碼分析調(diào)用時,會調(diào)用的方法,同時將新的作為參數(shù)傳進(jìn)會先調(diào)用獲取一個維護兩個時間一個 系列文章 React Fiber源碼分析 第一篇 React Fiber源碼分析 第二篇(同步模式) React Fiber源碼分析 第三篇(...

    worldligang 評論0 收藏0
  • 淺談React Fiber

    摘要:因為版本將真正廢棄這三生命周期到目前為止,的渲染機制遵循同步渲染首次渲染,更新時更新時卸載時期間每個周期函數(shù)各司其職,輸入輸出都是可預(yù)測,一路下來很順暢。通過進(jìn)一步觀察可以發(fā)現(xiàn),預(yù)廢棄的三個生命周期函數(shù)都發(fā)生在虛擬的構(gòu)建期間,也就是之前。 showImg(https://segmentfault.com/img/bVbweoj?w=559&h=300); 背景 前段時間準(zhǔn)備前端招聘事項...

    izhuhaodev 評論0 收藏0
  • React Fiber源碼分析 第二篇(同步模式)

    摘要:函數(shù)主要執(zhí)行兩個操作,一個是判斷當(dāng)前是否還有任務(wù),如果沒有,則從鏈中移除。 系列文章 React Fiber源碼分析 第一篇 React Fiber源碼分析 第二篇(同步模式) React Fiber源碼分析 第三篇(異步狀態(tài)) React Fiber源碼分析 第四篇(歸納總結(jié)) 前言 React Fiber是React在V16版本中的大更新,利用了閑余時間看了一些源碼,做個小記...

    OBKoro1 評論0 收藏0
  • Deep In React 之詳談 React 16 Diff 策略(二)

    摘要:對于同一層級的一組子節(jié)點,它們可以通過唯一進(jìn)行區(qū)分。基于以上三個前提策略,分別對以及進(jìn)行算法優(yōu)化。鏈表的每一個節(jié)點是,而不是在之前的虛擬節(jié)點。是當(dāng)前層的第一個節(jié)點。再次提醒,是的一層。 文章首發(fā)于個人博客 這是我 Deep In React 系列的第二篇文章,如果還沒有讀過的強烈建議你先讀第一篇:詳談 React Fiber 架構(gòu)(1)。 前言 我相信在看這篇文章的讀者一般都已經(jīng)了解...

    NSFish 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<