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

資訊專欄INFORMATION COLUMN

【Under-the-hood-ReactJS-Part14】React源碼解讀

molyzzx / 3449人閱讀

摘要:一種是子元素仍然是復(fù)雜對(duì)象,也就是說子元素還是組件,需要遞歸處理嵌套的子組件直到到達(dá)他們的內(nèi)容層級(jí)。處理方式是根據(jù)的類型來判斷的。在我們的列子中,組件組件有三個(gè)子元素,,和。現(xiàn)在我們要對(duì)元素內(nèi)容進(jìn)行更新,事實(shí)上,是替換它的內(nèi)容。

接上文,

React流程圖:
https://bogdan-lyashenko.gith...

最后的最后

更新方法基于子元素上的多個(gè)屬性去處理子元素。這里會(huì)有幾種場(chǎng)景,但是技術(shù)上來說主要是兩種。一種是子元素仍然是‘復(fù)雜’對(duì)象,也就是說子元素還是React組件,React需要遞歸處理嵌套的子組件直到到達(dá)他們的內(nèi)容層級(jí)。還有一種,就是子元素已經(jīng)是內(nèi)容層級(jí)里,內(nèi)容就是字符串或者數(shù)字或者其他簡單類型。

處理方式是根據(jù)nextProps.children的類型來判斷的。在我們的列子中,組件
組件有三個(gè)子元素,button,childCmp 和 text string。

我們看下它是如何運(yùn)作的。
在Examplication子元素的第一次迭代期間,子元素的類型不是內(nèi)容,所以需要進(jìn)入到‘復(fù)雜’組件的處理邏輯。我們遍歷所有的子元素,按之前處理它們父元素的過了處理它們。順便提下,驗(yàn)證shouldUpdateReactComponent的代碼塊會(huì)令人有點(diǎn)疑惑,表面上看起來這個(gè)是用來檢測(cè)是否需要更新,但是實(shí)際上,它除了檢測(cè)更新,還檢測(cè)刪除,新建操作(為了簡化流程圖,相應(yīng)的代碼沒有展示在流程圖中)。之后,我們將舊元素和當(dāng)前元素,如果一些子元素被移除了,則我們需要卸載對(duì)應(yīng)的組件并同時(shí)移除它。

接下去,在第二次迭代過程中,我們需要處理button,這個(gè)相對(duì)來說比較簡單,因?yàn)閎utton的子元素就是文本,內(nèi)容就是‘set state button"。我們檢測(cè)下之前的內(nèi)容是否跟現(xiàn)在的保持一致,嗯,文本沒有發(fā)生改變,所以我們不需要更新button。邏輯上來說這樣很正確,其實(shí)這就是虛擬DOM的作用,現(xiàn)在虛擬DOM聽起來就具體了些,是不是?React會(huì)維護(hù)內(nèi)部DOM,同時(shí)只在需要時(shí)才去處理真正的DOM節(jié)點(diǎn),通過這種方式,很自然的會(huì)提高性能。到這里,你應(yīng)該已經(jīng)能理解React的設(shè)計(jì)思想了,這之后,我們對(duì)ChildCmp進(jìn)行更新,它的子元素會(huì)被遍歷直到它的內(nèi)容層級(jí)并進(jìn)行更新。在我們的列子里,通過click和setState的調(diào)用,"click state message"會(huì)對(duì)this.props.message進(jìn)行更新。

//...
onClickHandler() {
    this.setState({ message: "click state message" });
}

render() {
    return 
//...

現(xiàn)在我們要對(duì)元素內(nèi)容進(jìn)行更新,事實(shí)上,是替換它的內(nèi)容。那么是如何進(jìn)行更新的呢?一個(gè)類似擁有配置信息的配置對(duì)象會(huì)被解析,并且配置對(duì)象里的定義的動(dòng)作會(huì)被執(zhí)行。對(duì)應(yīng)我們的例子,文本更新的配置會(huì)像如下:

{
  afterNode: null,
  content: "click state message",
  fromIndex: null,
  fromNode: null,
  toIndex: null,
  type: "TEXT_CONTENT"
}

正如你所見,它幾乎就是一個(gè)空對(duì)象,這個(gè)文本內(nèi)容更新例子是相當(dāng)直白的。配置對(duì)象里有很多字段,這是因?yàn)樵趯?duì)DOM節(jié)點(diǎn)進(jìn)行移動(dòng)時(shí),配置對(duì)象會(huì)比文本更新的配置對(duì)象相對(duì)來說會(huì)更復(fù)雜些:

看下源碼,這應(yīng)該會(huì)讓我們有個(gè)更清晰的認(rèn)識(shí):

//src
enderersdomclientutilsDOMChildrenOperations.js#172
processUpdates: function(parentNode, updates) {
    for (var k = 0; k < updates.length; k++) {
      var update = updates[k];

      switch (update.type) {
        case "INSERT_MARKUP":
          insertLazyTreeChildAt(
            parentNode,
            update.content,
            getNodeAfter(parentNode, update.afterNode)
          );
          break;
        case "MOVE_EXISTING":
          moveChild(
            parentNode,
            update.fromNode,
            getNodeAfter(parentNode, update.afterNode)
          );
          break;
        case "SET_MARKUP":
          setInnerHTML(
            parentNode,
            update.content
          );
          break;
        case "TEXT_CONTENT":
          setTextContent(
            parentNode,
            update.content
          );
          break;
        case "REMOVE_NODE":
          removeChild(parentNode, update.fromNode);
          break;
      }
    }
  }

我們的實(shí)例會(huì)走到"TEXT_CONTENT"的分支里,然后這就是最后一步了,React調(diào)用setTextContent方法,此方法會(huì)對(duì)真正的DOM節(jié)點(diǎn)進(jìn)行內(nèi)容更改。

不錯(cuò)不錯(cuò),最終內(nèi)部被更新到了頁面上,這就是一個(gè)重繪的過程了。還有什么東西沒有講到嗎?嗯,不要著急,讓我們先完成這個(gè)更新過程。所有的東西都已經(jīng)準(zhǔn)備完畢,所有我們組件的componentDidUpdate方法會(huì)被調(diào)用。那么,這種延遲調(diào)用是如何實(shí)現(xiàn)的呢?沒錯(cuò),就是使用事務(wù)包裝器。就像之前提到的,‘臟’組件的更新是被ReactUpdateFlushtransaction給包裝過的,其中一個(gè)包裝器里就有調(diào)用this.callbackQueue.notifyAll的邏輯,也就是在這里,componentDidUpdate會(huì)被調(diào)用。完美!

現(xiàn)在,我們真的完成了整個(gè)過程。

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

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

相關(guān)文章

  • Under-the-hood-ReactJS-Part11】React源碼解讀

    摘要:技術(shù)上來說,當(dāng)方法被調(diào)用后或者發(fā)生改變后,方法都會(huì)被調(diào)用。下一步,會(huì)設(shè)置為。之后,檢測(cè)當(dāng)前更新是否由更新引起的。這是因?yàn)椋褂檬菍?dǎo)致組件持久化更新,而會(huì)被方法的返回值重新賦值。 接上文, React流程圖:https://bogdan-lyashenko.gith... 更新組件 關(guān)于組件的更新,我們先看下代碼里的注釋: 對(duì)于已掛載組件的更新過程,React會(huì)首先調(diào)用component...

    hiyayiji 評(píng)論0 收藏0
  • Under-the-hood-ReactJS-Part8】React源碼解讀

    摘要:接上文,流程圖我們已經(jīng)知道掛載的工作流程,現(xiàn)在我們換個(gè)方向研究下方法,這個(gè)也是的重要組成部分。這個(gè)問題,我們會(huì)在下一篇文章中進(jìn)行解答。。。 接上文, React流程圖:https://bogdan-lyashenko.gith... this.setState 我們已經(jīng)知道掛載的工作流程,現(xiàn)在我們換個(gè)方向研究下--setState方法,這個(gè)也是React的重要組成部分。 首先,為什么我...

    zhoutk 評(píng)論0 收藏0
  • Under-the-hood-ReactJS-Part6】React源碼解讀

    摘要:源碼里有個(gè)獨(dú)立的模塊管理組件的所有子元素。第一個(gè),實(shí)例化子元素使用并掛載它們。至于具體掛載流程,基于子元素類型的不同而有不同的掛載過程。掛載的過程基本完成了。 接上文, React流程圖:https://bogdan-lyashenko.gith... 創(chuàng)建初始子組件 在之前的步驟里,組件本身的構(gòu)建已經(jīng)完成,接下去,我們分析它們的子元素。總共分為兩步:掛載子元素(this.mountC...

    codergarden 評(píng)論0 收藏0
  • Under-the-hood-ReactJS-Part9】React源碼解讀

    摘要:當(dāng)鼠標(biāo)事件發(fā)生時(shí),組件的最外層會(huì)進(jìn)行處理,然后通過幾層包裝器的處理后,會(huì)開始進(jìn)行批量更新操作。在這之后,會(huì)將這些事件處理成常見到樣子。 接上文, React流程圖:https://bogdan-lyashenko.gith... 回到最初 在流程圖中,也許你已經(jīng)注意到,setState方法可以通過幾種方式觸發(fā),更準(zhǔn)確的說,可以分為是否由外部引起的(也就是是否由用戶觸發(fā))。讓我們看下如下...

    SnaiLiu 評(píng)論0 收藏0
  • Under-the-hood-ReactJS-Part13】React源碼解讀

    摘要:接著,將返回的元素和之前的進(jìn)行比較的,以驗(yàn)證是否真的需要更新。我們看下代碼,代碼比較簡單好,對(duì)應(yīng)于我們的這個(gè)列子,我們對(duì)于方法的更改并不會(huì)對(duì)方法造成影響。所以我們進(jìn)入下一步,也就是對(duì)于節(jié)點(diǎn)的更新。 接上文, React流程圖:https://bogdan-lyashenko.gith... 如果組件真的需要更新 在組件剛開始更新過程時(shí),如果有定義componentWillUpdate方...

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

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

0條評(píng)論

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