摘要:一種是子元素仍然是復雜對象,也就是說子元素還是組件,需要遞歸處理嵌套的子組件直到到達他們的內容層級。處理方式是根據的類型來判斷的。在我們的列子中,組件組件有三個子元素,,和。現在我們要對元素內容進行更新,事實上,是替換它的內容。
接上文,
React流程圖:
https://bogdan-lyashenko.gith...
更新方法基于子元素上的多個屬性去處理子元素。這里會有幾種場景,但是技術上來說主要是兩種。一種是子元素仍然是‘復雜’對象,也就是說子元素還是React組件,React需要遞歸處理嵌套的子組件直到到達他們的內容層級。還有一種,就是子元素已經是內容層級里,內容就是字符串或者數字或者其他簡單類型。
處理方式是根據nextProps.children的類型來判斷的。在我們的列子中,組件
我們看下它是如何運作的。
在Examplication子元素的第一次迭代期間,子元素的類型不是內容,所以需要進入到‘復雜’組件的處理邏輯。我們遍歷所有的子元素,按之前處理它們父元素的過了處理它們。順便提下,驗證shouldUpdateReactComponent的代碼塊會令人有點疑惑,表面上看起來這個是用來檢測是否需要更新,但是實際上,它除了檢測更新,還檢測刪除,新建操作(為了簡化流程圖,相應的代碼沒有展示在流程圖中)。之后,我們將舊元素和當前元素,如果一些子元素被移除了,則我們需要卸載對應的組件并同時移除它。
接下去,在第二次迭代過程中,我們需要處理button,這個相對來說比較簡單,因為button的子元素就是文本,內容就是‘set state button"。我們檢測下之前的內容是否跟現在的保持一致,嗯,文本沒有發生改變,所以我們不需要更新button。邏輯上來說這樣很正確,其實這就是虛擬DOM的作用,現在虛擬DOM聽起來就具體了些,是不是?React會維護內部DOM,同時只在需要時才去處理真正的DOM節點,通過這種方式,很自然的會提高性能。到這里,你應該已經能理解React的設計思想了,這之后,我們對ChildCmp進行更新,它的子元素會被遍歷直到它的內容層級并進行更新。在我們的列子里,通過click和setState的調用,"click state message"會對this.props.message進行更新。
//... onClickHandler() { this.setState({ message: "click state message" }); } render() { return//... 現在我們要對元素內容進行更新,事實上,是替換它的內容。那么是如何進行更新的呢?一個類似擁有配置信息的配置對象會被解析,并且配置對象里的定義的動作會被執行。對應我們的例子,文本更新的配置會像如下:
{ afterNode: null, content: "click state message", fromIndex: null, fromNode: null, toIndex: null, type: "TEXT_CONTENT" }正如你所見,它幾乎就是一個空對象,這個文本內容更新例子是相當直白的。配置對象里有很多字段,這是因為在對DOM節點進行移動時,配置對象會比文本更新的配置對象相對來說會更復雜些:
看下源碼,這應該會讓我們有個更清晰的認識:
//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; } } }我們的實例會走到"TEXT_CONTENT"的分支里,然后這就是最后一步了,React調用setTextContent方法,此方法會對真正的DOM節點進行內容更改。
不錯不錯,最終內部被更新到了頁面上,這就是一個重繪的過程了。還有什么東西沒有講到嗎?嗯,不要著急,讓我們先完成這個更新過程。所有的東西都已經準備完畢,所有我們組件的componentDidUpdate方法會被調用。那么,這種延遲調用是如何實現的呢?沒錯,就是使用事務包裝器。就像之前提到的,‘臟’組件的更新是被ReactUpdateFlushtransaction給包裝過的,其中一個包裝器里就有調用this.callbackQueue.notifyAll的邏輯,也就是在這里,componentDidUpdate會被調用。完美!
現在,我們真的完成了整個過程。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95957.html
摘要:技術上來說,當方法被調用后或者發生改變后,方法都會被調用。下一步,會設置為。之后,檢測當前更新是否由更新引起的。這是因為,使用是導致組件持久化更新,而會被方法的返回值重新賦值。 接上文, React流程圖:https://bogdan-lyashenko.gith... 更新組件 關于組件的更新,我們先看下代碼里的注釋: 對于已掛載組件的更新過程,React會首先調用component...
摘要:接上文,流程圖我們已經知道掛載的工作流程,現在我們換個方向研究下方法,這個也是的重要組成部分。這個問題,我們會在下一篇文章中進行解答。。。 接上文, React流程圖:https://bogdan-lyashenko.gith... this.setState 我們已經知道掛載的工作流程,現在我們換個方向研究下--setState方法,這個也是React的重要組成部分。 首先,為什么我...
摘要:源碼里有個獨立的模塊管理組件的所有子元素。第一個,實例化子元素使用并掛載它們。至于具體掛載流程,基于子元素類型的不同而有不同的掛載過程。掛載的過程基本完成了。 接上文, React流程圖:https://bogdan-lyashenko.gith... 創建初始子組件 在之前的步驟里,組件本身的構建已經完成,接下去,我們分析它們的子元素。總共分為兩步:掛載子元素(this.mountC...
摘要:當鼠標事件發生時,組件的最外層會進行處理,然后通過幾層包裝器的處理后,會開始進行批量更新操作。在這之后,會將這些事件處理成常見到樣子。 接上文, React流程圖:https://bogdan-lyashenko.gith... 回到最初 在流程圖中,也許你已經注意到,setState方法可以通過幾種方式觸發,更準確的說,可以分為是否由外部引起的(也就是是否由用戶觸發)。讓我們看下如下...
摘要:接著,將返回的元素和之前的進行比較的,以驗證是否真的需要更新。我們看下代碼,代碼比較簡單好,對應于我們的這個列子,我們對于方法的更改并不會對方法造成影響。所以我們進入下一步,也就是對于節點的更新。 接上文, React流程圖:https://bogdan-lyashenko.gith... 如果組件真的需要更新 在組件剛開始更新過程時,如果有定義componentWillUpdate方...
閱讀 1963·2021-10-25 09:48
閱讀 2782·2021-09-22 14:59
閱讀 1755·2019-08-29 16:52
閱讀 854·2019-08-29 16:07
閱讀 2298·2019-08-29 12:38
閱讀 1751·2019-08-26 13:23
閱讀 875·2019-08-26 11:49
閱讀 3264·2019-08-26 10:56